infrakit-cli 0.1.14__py3-none-any.whl
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.
- infrakit_cli/__init__.py +114 -0
- infrakit_cli/agent_config.py +95 -0
- infrakit_cli/banner.py +47 -0
- infrakit_cli/bootstrap.py +184 -0
- infrakit_cli/cli.py +847 -0
- infrakit_cli/console.py +10 -0
- infrakit_cli/git_utils.py +78 -0
- infrakit_cli/github_api.py +104 -0
- infrakit_cli/iac_config.py +83 -0
- infrakit_cli/interactive.py +124 -0
- infrakit_cli/mcp.py +117 -0
- infrakit_cli/mcp_config.py +43 -0
- infrakit_cli/skills.py +281 -0
- infrakit_cli/template_renderer.py +426 -0
- infrakit_cli/templates/agent_personas/cloud_architect.md +190 -0
- infrakit_cli/templates/agent_personas/cloud_security_engineer.md +249 -0
- infrakit_cli/templates/agent_personas/cloud_solutions_engineer.md +131 -0
- infrakit_cli/templates/commands/analyze.md +238 -0
- infrakit_cli/templates/commands/architect-review.md +221 -0
- infrakit_cli/templates/commands/security-review.md +208 -0
- infrakit_cli/templates/commands/setup.md +413 -0
- infrakit_cli/templates/commands/status.md +125 -0
- infrakit_cli/templates/iac/crossplane/agent_personas/crossplane_engineer.md +263 -0
- infrakit_cli/templates/iac/crossplane/assets/coding-style-template.md +381 -0
- infrakit_cli/templates/iac/crossplane/commands/implement.md +301 -0
- infrakit_cli/templates/iac/crossplane/commands/new_composition.md +400 -0
- infrakit_cli/templates/iac/crossplane/commands/plan.md +332 -0
- infrakit_cli/templates/iac/crossplane/commands/review.md +239 -0
- infrakit_cli/templates/iac/crossplane/commands/setup-coding-style.md +249 -0
- infrakit_cli/templates/iac/crossplane/commands/update_composition.md +659 -0
- infrakit_cli/templates/iac/terraform/agent_personas/terraform_engineer.md +232 -0
- infrakit_cli/templates/iac/terraform/assets/coding-style-template.md +404 -0
- infrakit_cli/templates/iac/terraform/commands/create_terraform_code.md +390 -0
- infrakit_cli/templates/iac/terraform/commands/implement.md +303 -0
- infrakit_cli/templates/iac/terraform/commands/plan.md +295 -0
- infrakit_cli/templates/iac/terraform/commands/review.md +248 -0
- infrakit_cli/templates/iac/terraform/commands/setup-coding-style.md +231 -0
- infrakit_cli/templates/iac/terraform/commands/update_terraform_code.md +666 -0
- infrakit_cli/templates/project-context-template.md +174 -0
- infrakit_cli/templates/tagging-standard-template.md +55 -0
- infrakit_cli/templates/vscode-settings.json +12 -0
- infrakit_cli/tools.py +81 -0
- infrakit_cli/tracker.py +115 -0
- infrakit_cli-0.1.14.dist-info/METADATA +591 -0
- infrakit_cli-0.1.14.dist-info/RECORD +48 -0
- infrakit_cli-0.1.14.dist-info/WHEEL +4 -0
- infrakit_cli-0.1.14.dist-info/entry_points.txt +2 -0
- infrakit_cli-0.1.14.dist-info/licenses/LICENSE +22 -0
infrakit_cli/__init__.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""InfraKit CLI — spec-kit for IaC, with a multi-persona pipeline.
|
|
2
|
+
|
|
3
|
+
The package's public API is split into focused submodules:
|
|
4
|
+
|
|
5
|
+
- :mod:`infrakit_cli.cli` — the Typer app, the four user-facing commands
|
|
6
|
+
(``init``, ``check``, ``mcp``, ``version``), and the ``main()`` entry point.
|
|
7
|
+
- :mod:`infrakit_cli.bootstrap` — ``initialize_iac_config()`` materialises
|
|
8
|
+
``.infrakit/`` and ``.infrakit_tracks/`` on a freshly-initialised project.
|
|
9
|
+
- :mod:`infrakit_cli.template_renderer` — runtime per-agent transformer.
|
|
10
|
+
- :mod:`infrakit_cli.skills` — installs prompt files as agent skills.
|
|
11
|
+
- :mod:`infrakit_cli.mcp` — MCP recipe install helpers.
|
|
12
|
+
- :mod:`infrakit_cli.tracker` — :class:`StepTracker` UI primitive.
|
|
13
|
+
- :mod:`infrakit_cli.interactive` — keyboard input + arrow-key menu.
|
|
14
|
+
- :mod:`infrakit_cli.banner` — ASCII banner and Typer group override.
|
|
15
|
+
- :mod:`infrakit_cli.tools` — subprocess + tool-detection helpers.
|
|
16
|
+
- :mod:`infrakit_cli.git_utils` — repo detection + ``git init`` wrapper.
|
|
17
|
+
- :mod:`infrakit_cli.github_api` — token/auth/rate-limit helpers for the
|
|
18
|
+
optional ``infrakit version`` check.
|
|
19
|
+
- :mod:`infrakit_cli.console` — shared :class:`rich.console.Console` instance.
|
|
20
|
+
|
|
21
|
+
The top-level :func:`main` function (re-exported below) is the
|
|
22
|
+
``project.scripts`` entry point: ``infrakit = "infrakit_cli:main"``.
|
|
23
|
+
|
|
24
|
+
The other re-exports preserve a stable import surface so that existing tests
|
|
25
|
+
and downstream callers continue to use ``from infrakit_cli import X``.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from .banner import BannerGroup, show_banner
|
|
29
|
+
from .bootstrap import initialize_iac_config
|
|
30
|
+
from .cli import app, callback, check, init, main, mcp, version
|
|
31
|
+
from .console import console
|
|
32
|
+
from .git_utils import init_git_repo, is_git_repo
|
|
33
|
+
from .github_api import (
|
|
34
|
+
_format_rate_limit_error,
|
|
35
|
+
_github_auth_headers,
|
|
36
|
+
_github_token,
|
|
37
|
+
_parse_rate_limit_headers,
|
|
38
|
+
client,
|
|
39
|
+
ssl_context,
|
|
40
|
+
)
|
|
41
|
+
from .interactive import get_key, select_with_arrows
|
|
42
|
+
from .mcp import (
|
|
43
|
+
_build_mcp_markdown_block,
|
|
44
|
+
_build_mcp_server_entry,
|
|
45
|
+
_read_mcp_json,
|
|
46
|
+
_update_mcp_use_table,
|
|
47
|
+
)
|
|
48
|
+
from .skills import (
|
|
49
|
+
AGENT_SKILLS_DIR_OVERRIDES,
|
|
50
|
+
DEFAULT_SKILLS_DIR,
|
|
51
|
+
SKILL_DESCRIPTIONS,
|
|
52
|
+
_get_skills_dir,
|
|
53
|
+
ensure_project_context_from_template,
|
|
54
|
+
install_ai_skills,
|
|
55
|
+
)
|
|
56
|
+
from .tools import (
|
|
57
|
+
CLAUDE_LOCAL_PATH,
|
|
58
|
+
SCRIPT_TYPE_CHOICES,
|
|
59
|
+
check_tool,
|
|
60
|
+
find_project_root,
|
|
61
|
+
run_command,
|
|
62
|
+
)
|
|
63
|
+
from .tracker import StepTracker
|
|
64
|
+
|
|
65
|
+
__all__ = [
|
|
66
|
+
# Typer app + commands
|
|
67
|
+
"app",
|
|
68
|
+
"callback",
|
|
69
|
+
"check",
|
|
70
|
+
"init",
|
|
71
|
+
"main",
|
|
72
|
+
"mcp",
|
|
73
|
+
"version",
|
|
74
|
+
# UI primitives
|
|
75
|
+
"BannerGroup",
|
|
76
|
+
"console",
|
|
77
|
+
"show_banner",
|
|
78
|
+
"StepTracker",
|
|
79
|
+
"select_with_arrows",
|
|
80
|
+
"get_key",
|
|
81
|
+
# Project bootstrap
|
|
82
|
+
"initialize_iac_config",
|
|
83
|
+
"ensure_project_context_from_template",
|
|
84
|
+
# Tools / git
|
|
85
|
+
"check_tool",
|
|
86
|
+
"find_project_root",
|
|
87
|
+
"init_git_repo",
|
|
88
|
+
"is_git_repo",
|
|
89
|
+
"run_command",
|
|
90
|
+
"CLAUDE_LOCAL_PATH",
|
|
91
|
+
"SCRIPT_TYPE_CHOICES",
|
|
92
|
+
# MCP
|
|
93
|
+
"_build_mcp_markdown_block",
|
|
94
|
+
"_build_mcp_server_entry",
|
|
95
|
+
"_read_mcp_json",
|
|
96
|
+
"_update_mcp_use_table",
|
|
97
|
+
# Skills
|
|
98
|
+
"AGENT_SKILLS_DIR_OVERRIDES",
|
|
99
|
+
"DEFAULT_SKILLS_DIR",
|
|
100
|
+
"SKILL_DESCRIPTIONS",
|
|
101
|
+
"_get_skills_dir",
|
|
102
|
+
"install_ai_skills",
|
|
103
|
+
# GitHub API helpers (used by the version command)
|
|
104
|
+
"_format_rate_limit_error",
|
|
105
|
+
"_github_auth_headers",
|
|
106
|
+
"_github_token",
|
|
107
|
+
"_parse_rate_limit_headers",
|
|
108
|
+
"client",
|
|
109
|
+
"ssl_context",
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if __name__ == "__main__":
|
|
114
|
+
main()
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent configurations for infrakit-cli.
|
|
3
|
+
|
|
4
|
+
Five AI coding agents are supported. Each entry's runtime-rendering keys
|
|
5
|
+
mirror what :mod:`template_renderer` consumes:
|
|
6
|
+
|
|
7
|
+
- ``folder``: agent-specific root directory under the project (e.g. ``.claude/``).
|
|
8
|
+
- ``commands_subdir``: subdir under ``folder`` where rendered commands live.
|
|
9
|
+
- ``command_format``: ``markdown`` | ``toml`` | ``agent.md``.
|
|
10
|
+
- ``command_args``: the token that replaces ``{ARGS}`` in command bodies.
|
|
11
|
+
- ``command_extension``: the file extension applied to ``infrakit:<name>``.
|
|
12
|
+
- ``supports_subagents``: whether the agent has a built-in subagent
|
|
13
|
+
invocation primitive (Claude Code's ``Task`` tool). The multi-persona
|
|
14
|
+
commands check this to decide whether to delegate review phases.
|
|
15
|
+
- ``extras`` (optional list): post-render hooks. Recognised values:
|
|
16
|
+
* ``"copilot_prompts"`` — for every ``infrakit:*.agent.md`` produced,
|
|
17
|
+
also emit a companion ``infrakit:*.prompt.md`` with ``agent:``
|
|
18
|
+
frontmatter.
|
|
19
|
+
* ``"vscode_settings"`` — copy ``templates/vscode-settings.json`` to
|
|
20
|
+
``.vscode/settings.json``.
|
|
21
|
+
|
|
22
|
+
InfraKit historically supported 19 agents but the per-agent surface area
|
|
23
|
+
(layout differences, MCP install paths, command-format quirks) was
|
|
24
|
+
unmaintainable. The supported set is now the five agents we actively
|
|
25
|
+
test: Claude Code, Codex CLI, Gemini CLI, GitHub Copilot, plus a
|
|
26
|
+
``generic`` fallback for bring-your-own-agent setups.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Default values for agent metadata.
|
|
30
|
+
DEFAULT_FORMAT = "markdown"
|
|
31
|
+
DEFAULT_ARGS = "$ARGUMENTS"
|
|
32
|
+
DEFAULT_EXTENSION = ".md"
|
|
33
|
+
|
|
34
|
+
AGENT_CONFIG = {
|
|
35
|
+
"claude": {
|
|
36
|
+
"name": "Claude Code",
|
|
37
|
+
"folder": ".claude/",
|
|
38
|
+
"commands_subdir": "commands",
|
|
39
|
+
"install_url": "https://docs.anthropic.com/en/docs/claude-code/setup",
|
|
40
|
+
"requires_cli": True,
|
|
41
|
+
"command_format": DEFAULT_FORMAT,
|
|
42
|
+
"command_args": DEFAULT_ARGS,
|
|
43
|
+
"command_extension": DEFAULT_EXTENSION,
|
|
44
|
+
"mcp_install_path": ".mcp.json",
|
|
45
|
+
"supports_subagents": True,
|
|
46
|
+
# Render persona files into .claude/agents/ so the Task tool can
|
|
47
|
+
# invoke them by subagent_type matching the frontmatter `name:`.
|
|
48
|
+
"extras": ["claude_subagents"],
|
|
49
|
+
},
|
|
50
|
+
"codex": {
|
|
51
|
+
"name": "Codex CLI",
|
|
52
|
+
"folder": ".codex/",
|
|
53
|
+
"commands_subdir": "prompts",
|
|
54
|
+
"install_url": "https://github.com/openai/codex",
|
|
55
|
+
"requires_cli": True,
|
|
56
|
+
"command_format": DEFAULT_FORMAT,
|
|
57
|
+
"command_args": DEFAULT_ARGS,
|
|
58
|
+
"command_extension": DEFAULT_EXTENSION,
|
|
59
|
+
"supports_subagents": False,
|
|
60
|
+
},
|
|
61
|
+
"gemini": {
|
|
62
|
+
"name": "Gemini CLI",
|
|
63
|
+
"folder": ".gemini/",
|
|
64
|
+
"commands_subdir": "commands",
|
|
65
|
+
"install_url": "https://github.com/google-gemini/gemini-cli",
|
|
66
|
+
"requires_cli": True,
|
|
67
|
+
"command_format": "toml",
|
|
68
|
+
"command_args": "{{args}}",
|
|
69
|
+
"command_extension": ".toml",
|
|
70
|
+
"supports_subagents": False,
|
|
71
|
+
},
|
|
72
|
+
"copilot": {
|
|
73
|
+
"name": "GitHub Copilot",
|
|
74
|
+
"folder": ".github/",
|
|
75
|
+
"commands_subdir": "agents",
|
|
76
|
+
"install_url": None,
|
|
77
|
+
"requires_cli": False,
|
|
78
|
+
"command_format": "agent.md",
|
|
79
|
+
"command_args": DEFAULT_ARGS,
|
|
80
|
+
"command_extension": ".agent.md",
|
|
81
|
+
"extras": ["copilot_prompts", "vscode_settings"],
|
|
82
|
+
"supports_subagents": False,
|
|
83
|
+
},
|
|
84
|
+
"generic": {
|
|
85
|
+
"name": "Generic (bring your own agent)",
|
|
86
|
+
"folder": ".infrakit/",
|
|
87
|
+
"commands_subdir": "commands",
|
|
88
|
+
"install_url": None,
|
|
89
|
+
"requires_cli": False,
|
|
90
|
+
"command_format": DEFAULT_FORMAT,
|
|
91
|
+
"command_args": DEFAULT_ARGS,
|
|
92
|
+
"command_extension": DEFAULT_EXTENSION,
|
|
93
|
+
"supports_subagents": False,
|
|
94
|
+
},
|
|
95
|
+
}
|
infrakit_cli/banner.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""ASCII banner displayed at the top of every ``infrakit`` command run.
|
|
2
|
+
|
|
3
|
+
:class:`BannerGroup` overrides Typer's group class so that ``infrakit --help``
|
|
4
|
+
also prints the banner before the help text.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from rich.align import Align
|
|
10
|
+
from rich.text import Text
|
|
11
|
+
from typer.core import TyperGroup
|
|
12
|
+
|
|
13
|
+
from .console import console
|
|
14
|
+
|
|
15
|
+
BANNER = """
|
|
16
|
+
██╗███╗ ██╗███████╗██████╗ █████╗ ██╗ ██╗██╗████████╗
|
|
17
|
+
██║████╗ ██║██╔════╝██╔══██╗██╔══██╗██║ ██╔╝██║╚══██╔══╝
|
|
18
|
+
██║██╔██╗ ██║█████╗ ██████╔╝███████║█████╔╝ ██║ ██║
|
|
19
|
+
██║██║╚██╗██║██╔══╝ ██╔══██╗██╔══██║██╔═██╗ ██║ ██║
|
|
20
|
+
██║██║ ╚████║██║ ██║ ██║██║ ██║██║ ██╗██║ ██║
|
|
21
|
+
╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
TAGLINE = "InfraKit — spec-kit for IaC, with a multi-persona pipeline"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def show_banner():
|
|
28
|
+
"""Render the ASCII banner with a gradient and the project tagline beneath."""
|
|
29
|
+
banner_lines = BANNER.strip().split("\n")
|
|
30
|
+
colors = ["bright_blue", "blue", "cyan", "bright_cyan", "white", "bright_white"]
|
|
31
|
+
|
|
32
|
+
styled_banner = Text()
|
|
33
|
+
for i, line in enumerate(banner_lines):
|
|
34
|
+
color = colors[i % len(colors)]
|
|
35
|
+
styled_banner.append(line + "\n", style=color)
|
|
36
|
+
|
|
37
|
+
console.print(Align.center(styled_banner))
|
|
38
|
+
console.print(Align.center(Text(TAGLINE, style="italic bright_yellow")))
|
|
39
|
+
console.print()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class BannerGroup(TyperGroup):
|
|
43
|
+
"""Typer group that prints the banner ahead of ``--help`` output."""
|
|
44
|
+
|
|
45
|
+
def format_help(self, ctx, formatter):
|
|
46
|
+
show_banner()
|
|
47
|
+
super().format_help(ctx, formatter)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""IaC project bootstrap — writes ``.infrakit/`` and ``.infrakit_tracks/``.
|
|
2
|
+
|
|
3
|
+
:func:`initialize_iac_config` is the single function called by
|
|
4
|
+
``infrakit init`` (and the corresponding tests) to materialise everything a
|
|
5
|
+
freshly-bootstrapped InfraKit project needs:
|
|
6
|
+
|
|
7
|
+
- ``.infrakit/config.yaml`` recording the selected IaC tool + AI assistant
|
|
8
|
+
- ``.infrakit/context.md`` + ``.infrakit/coding-style.md`` (from IaC-specific assets)
|
|
9
|
+
- ``.infrakit/tagging-standard.md`` (shared template)
|
|
10
|
+
- ``.infrakit/mcp-use.md`` (empty installed-MCP index)
|
|
11
|
+
- ``.infrakit/memory/`` (project memory directory)
|
|
12
|
+
- ``.infrakit_tracks/tracks.md`` (master resource registry)
|
|
13
|
+
- ``.infrakit_tracks/tracks/`` (per-track working directories)
|
|
14
|
+
- Rendered slash commands + personas via
|
|
15
|
+
:func:`infrakit_cli.template_renderer.materialize_project`.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import shutil
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Optional
|
|
23
|
+
|
|
24
|
+
import yaml
|
|
25
|
+
|
|
26
|
+
from .agent_config import AGENT_CONFIG
|
|
27
|
+
from .iac_config import IAC_CONFIG
|
|
28
|
+
from .template_renderer import materialize_project, templates_root
|
|
29
|
+
from .tracker import StepTracker
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def initialize_iac_config(
|
|
33
|
+
project_path: Path,
|
|
34
|
+
iac_tool: str,
|
|
35
|
+
ai_assistant: str,
|
|
36
|
+
*,
|
|
37
|
+
tracker: Optional[StepTracker] = None,
|
|
38
|
+
) -> None:
|
|
39
|
+
"""Set up IaC-specific configuration, commands, agents, and documentation.
|
|
40
|
+
|
|
41
|
+
Creates:
|
|
42
|
+
|
|
43
|
+
- ``.infrakit/config.yaml`` — selected IaC tool and AI agent
|
|
44
|
+
- ``.infrakit/context.md`` — project context template (copied if absent)
|
|
45
|
+
- ``.infrakit/coding-style.md`` — default coding standards (copied if absent)
|
|
46
|
+
- ``.infrakit/tagging-standard.md`` — shared tagging template (copied if absent)
|
|
47
|
+
- ``.infrakit/mcp-use.md`` — installed MCP server index (created if absent)
|
|
48
|
+
- ``.infrakit/memory/`` — per-project memory directory
|
|
49
|
+
- ``.infrakit_tracks/tracks.md`` — master resource registry
|
|
50
|
+
- ``.infrakit_tracks/tracks/`` — track working directories
|
|
51
|
+
- Rendered IaC-native commands in the agent's commands directory
|
|
52
|
+
- Rendered IaC + generic personas under ``.infrakit/agent_personas/``
|
|
53
|
+
"""
|
|
54
|
+
iac_cfg = IAC_CONFIG.get(iac_tool, {})
|
|
55
|
+
if not iac_cfg:
|
|
56
|
+
if tracker:
|
|
57
|
+
tracker.error("iac-config", f"unknown IaC tool: {iac_tool}")
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
tpl_root = templates_root()
|
|
61
|
+
iac_templates_dir = tpl_root / "iac" / iac_tool
|
|
62
|
+
|
|
63
|
+
# --- 1. Create .infrakit/ configuration directory --------------------
|
|
64
|
+
|
|
65
|
+
if tracker:
|
|
66
|
+
tracker.start("iac-config")
|
|
67
|
+
|
|
68
|
+
infrakit_dir = project_path / ".infrakit"
|
|
69
|
+
infrakit_dir.mkdir(parents=True, exist_ok=True)
|
|
70
|
+
|
|
71
|
+
infrakit_tracks_dir = project_path / ".infrakit_tracks"
|
|
72
|
+
infrakit_tracks_dir.mkdir(parents=True, exist_ok=True)
|
|
73
|
+
|
|
74
|
+
# config.yaml — never overwritten on subsequent init runs.
|
|
75
|
+
config_data = {
|
|
76
|
+
"iac_tool": iac_tool,
|
|
77
|
+
"iac_name": iac_cfg.get("name", iac_tool),
|
|
78
|
+
"ai_assistant": ai_assistant,
|
|
79
|
+
"resource_term": iac_cfg.get("resource_term", "composition"),
|
|
80
|
+
}
|
|
81
|
+
config_file = infrakit_dir / "config.yaml"
|
|
82
|
+
if not config_file.exists():
|
|
83
|
+
config_file.write_text(
|
|
84
|
+
yaml.dump(config_data, sort_keys=False), encoding="utf-8"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Copy assets (context.md, coding-style.md) from the IaC asset templates.
|
|
88
|
+
assets_dir = iac_templates_dir / "assets"
|
|
89
|
+
if assets_dir.is_dir():
|
|
90
|
+
for asset_file in assets_dir.iterdir():
|
|
91
|
+
if asset_file.is_file():
|
|
92
|
+
dest = infrakit_dir / asset_file.name.replace(
|
|
93
|
+
"context_template", "context"
|
|
94
|
+
).replace("default_coding_style", "coding-style").replace(
|
|
95
|
+
"coding-style-template", "coding-style"
|
|
96
|
+
)
|
|
97
|
+
if not dest.exists():
|
|
98
|
+
shutil.copy2(asset_file, dest)
|
|
99
|
+
|
|
100
|
+
# tracks.md — master resource registry.
|
|
101
|
+
tracks_md = infrakit_tracks_dir / "tracks.md"
|
|
102
|
+
if not tracks_md.exists():
|
|
103
|
+
tracks_md.write_text(
|
|
104
|
+
"# Infrastructure Resource Registry\n\n"
|
|
105
|
+
"Track all infrastructure compositions and their current status.\n\n"
|
|
106
|
+
"## Status Reference\n\n"
|
|
107
|
+
"| Symbol | Meaning |\n"
|
|
108
|
+
"|--------|---------|\n"
|
|
109
|
+
"| 🔵 `initializing` | Track created, spec in progress |\n"
|
|
110
|
+
"| 📝 `spec-generated` | Spec confirmed, ready for plan |\n"
|
|
111
|
+
"| 📋 `planned` | Plan generated, ready for implementation |\n"
|
|
112
|
+
"| ⚙️ `in-progress` | Implementation underway |\n"
|
|
113
|
+
"| ✅ `done` | Implementation complete and reviewed |\n"
|
|
114
|
+
"| ❌ `blocked` | Blocked, needs attention |\n\n"
|
|
115
|
+
"---\n\n"
|
|
116
|
+
"## Tracks\n\n"
|
|
117
|
+
"| Track | Type | Directory | Status | Created |\n"
|
|
118
|
+
"|-------|------|-----------|--------|---------|\n"
|
|
119
|
+
"| (none yet) | — | — | — | — |\n",
|
|
120
|
+
encoding="utf-8",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# tagging-standard.md — shared, IaC-agnostic tagging standard.
|
|
124
|
+
tagging_std_md = infrakit_dir / "tagging-standard.md"
|
|
125
|
+
if not tagging_std_md.exists():
|
|
126
|
+
shared_tagging_template = tpl_root / "tagging-standard-template.md"
|
|
127
|
+
if shared_tagging_template.is_file():
|
|
128
|
+
shutil.copy2(shared_tagging_template, tagging_std_md)
|
|
129
|
+
else:
|
|
130
|
+
tagging_std_md.write_text(
|
|
131
|
+
"# Tagging Standard\n\n"
|
|
132
|
+
"> Run `/infrakit:setup` to configure your project-specific tagging requirements.\n",
|
|
133
|
+
encoding="utf-8",
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# mcp-use.md — installed MCP server index.
|
|
137
|
+
mcp_use_md = infrakit_dir / "mcp-use.md"
|
|
138
|
+
if not mcp_use_md.exists():
|
|
139
|
+
mcp_use_md.write_text(
|
|
140
|
+
"# Installed MCP Servers\n\n"
|
|
141
|
+
"MCP servers configured for this project.\n"
|
|
142
|
+
"Run `infrakit mcp` to add more.\n\n"
|
|
143
|
+
"| MCP | Description | Tools | Usage |\n"
|
|
144
|
+
"|-----|-------------|-------|-------|\n"
|
|
145
|
+
"| — | — | — | — |\n",
|
|
146
|
+
encoding="utf-8",
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Memory directory (for project context).
|
|
150
|
+
(infrakit_dir / "memory").mkdir(parents=True, exist_ok=True)
|
|
151
|
+
|
|
152
|
+
# Per-track working directories live under .infrakit_tracks/tracks/.
|
|
153
|
+
tracks_dir = infrakit_tracks_dir / "tracks"
|
|
154
|
+
tracks_dir.mkdir(parents=True, exist_ok=True)
|
|
155
|
+
|
|
156
|
+
if tracker:
|
|
157
|
+
tracker.complete("iac-config", f"{iac_tool} ({iac_cfg.get('name', '')})")
|
|
158
|
+
|
|
159
|
+
# --- 2. Render commands + personas via the runtime renderer ---------
|
|
160
|
+
|
|
161
|
+
if tracker:
|
|
162
|
+
tracker.start("iac-commands")
|
|
163
|
+
|
|
164
|
+
counts = materialize_project(
|
|
165
|
+
project_path,
|
|
166
|
+
ai_assistant=ai_assistant,
|
|
167
|
+
iac_tool=iac_tool,
|
|
168
|
+
overwrite=False,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
agent_cfg = AGENT_CONFIG.get(ai_assistant, {})
|
|
172
|
+
agent_folder = (agent_cfg.get("folder") or "").rstrip("/")
|
|
173
|
+
commands_subdir = agent_cfg.get("commands_subdir", "commands")
|
|
174
|
+
cmds_dest = (
|
|
175
|
+
project_path / agent_folder / commands_subdir
|
|
176
|
+
if agent_folder
|
|
177
|
+
else project_path / commands_subdir
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if tracker:
|
|
181
|
+
tracker.complete(
|
|
182
|
+
"iac-commands",
|
|
183
|
+
f"{counts['generic_commands']} generic + {counts['iac_commands']} IaC commands → {cmds_dest.relative_to(project_path)}",
|
|
184
|
+
)
|