This file applies to the entire repository.
iac-codeis a Python 3.10+ Infrastructure as Code assistant focused on Alibaba Cloud ROS / Terraform template generation and management.- Source code uses a
src/layout with the main package atsrc/iac_code/and tests attests/. - The CLI entry point is declared in
pyproject.tomlasiac-code = "iac_code.cli.main:app". Beyond the default interactive REPL, the same entry point exposes additional run modes as subcommands:iac-code web(local Web app),iac-code acp(ACP server),iac-code a2a(A2A 1.0 server),iac-code mcp ...(MCP management), andiac-code a2a-client ...(A2A client). - The native Desktop application uses Tauri 2 with the Python package bundled as a sidecar. It is a desktop shell for the existing product rather than a separate implementation of the agent or Web application.
- The repository also ships an external iac-code Skill package (
skills/iac-code/) and a CPython 3.12 Skill Runtime release pipeline (skill-runtime/) so external agents can operate iac-code over A2A.
- Install dependencies and hooks:
make install - Run tests:
make test(current interpreter;make test PY=allruns the full 3.10–3.14 matrix,make test PY=3.xruns one version; tests run in parallel via-n auto) - Run coverage:
make coverage - Run lint and type check:
make lint(runs bothruff checkandty check src/) - Format code:
make format - Extract, update, and compile translations (both
messagesandwebuidomains):make translate - Start CLI locally:
make run - Start CLI in debug mode:
make dev - Run Desktop Python tests:
uv run pytest -q tests/desktop - Run Desktop host tests:
cargo test --manifest-path desktop/src-tauri/Cargo.toml - Run Desktop updater tests:
cargo test --manifest-path desktop/src-tauri/Cargo.toml --features updater - Run Desktop helper tests:
cargo test --manifest-path desktop/helpers/Cargo.toml - Install Desktop JavaScript dependencies:
cd desktop && npm ci - Build a native Desktop package from
desktop/:npm run build:macos,npm run build:windows,npm run build:appimage, ornpm run build:deb
Prefer using uv and existing Makefile targets. When adding new dependencies, update pyproject.toml and uv.lock — do not bypass the project's dependency management.
- The product version has a single source:
__version__insrc/iac_code/__init__.py.pyproject.toml,setup.py, the Makefile, and the Desktop sync script all derive it from there. - Bump the version with
make bump-version VERSION=x.y.z. It validates SemVer, updates__version__, refreshes theProject-Id-Versionheader in everymessages.po, and runsdesktop/scripts/sync_version.pyto sync the Desktoppackage.json/package-lock.json,tauri.conf.json, Cargo manifests, and lockfiles. - Do not hand-edit the synced Desktop version fields;
make desktop-testand CI runsync_version.py --checkand fail on drift. - Commit all files touched by one bump together in a single commit.
- Target version is Python 3.10; use modern type annotations and standard library capabilities. The codebase must stay compatible across the 3.10–3.14 test matrix.
- Ruff is configured in
pyproject.toml: line width 120,target-version = "py310", lint rulesE/F/I/N/Wenabled. Type checking usesty(Astral's type checker), not mypy. - Keep changes focused; do not refactor, rename, or move files outside the scope of the current task.
- Follow existing module boundaries. User-facing interfaces:
cli/— Typer CLI application and subcommands (default REPL plus theweb/acp/a2a/mcprun modes).ui/— terminal REPL UI (components, dialogs, keybindings, input suggestions).web/— local Web app: server, session/runtime management, SSE event bridging, output/diagram derivation, and thestatic/frontend.desktop/— Tauri/Rust host, bootstrap and recovery UI, installers, icons, native packaging, and release automation.src/iac_code/desktop/— Python Desktop runtime for control IPC, loopback ports, subprocess environment, Git Bash and tool discovery, diagnostics, and installation recovery.desktop/sidecar/sidecar_entry.pydelegates toiac_code.desktop.__main__.
- External Skill integration (repository root, distinct from the bundled agent skills in
src/iac_code/skills/):skills/iac-code/— the packaged external Skill:SKILL.md, agent metadata (agents/), andscripts/iac_code.py, a bridge that drives iac-code over A2A. The bridge must stay standard-library-only and compatible with Python 3.8+ (CI compiles and smoke-runs it on 3.8–3.14); do not add third-party imports or newer-only syntax.tests/skill_bridge/validates the bridge and the release scripts offline — keep those tests free of network and cloud dependencies.skill-runtime/— release tooling for the CPython 3.12 Skill Runtime executable (build/package/manifest scripts and PyInstaller spec) plus the skill-package and publisher contracts. Build outputs go toskill-runtime/dist/(git-ignored); never commit runtime archives, skill ZIPs, or generated manifests.
- Agent core:
agent/— agent loop, system prompts, and message types.commands/— REPL commands.tools/— agent-callable tools (includingbash/andcloud/).skills/— skill loading, rendering, discovery, and bundled skill resources (bundled/).memory/— project and agent memory management and recall.
- Providers and services:
providers/— LLM provider adapters.services/— session, context, credentials, capabilities, permissions, telemetry, and other business services.services/configuration_readiness.py— non-secret readiness report (LLM + Alibaba Cloud credential completeness) for runtimes that embed iac-code.
- Cloud resource selection:
resource_selector/— selector profiles and capabilities, the allowlisted query/response-projection layer, parameter/result validation, and the model-facingresolve_cloud_resource_selectorandselect_cloud_resourcetools. This feature is limited to selecting one cloud resource or one value derived from a selected resource.- The selector tools use the same effective Alibaba Cloud credential decision as
aliyun_api. Web and Desktop use the normal local credential chain. A2A gives request/session credentials priority and otherwise falls back to local configuration, environment variables, and Alibaba Cloud CLI credentials. If no valid effective credential exists, neither selector tool is registered. - A2A additionally requires
IAC_CODE_A2A_RESOURCE_SELECTOR_ENABLED; it does not require a client capability orprofileHashat runtime. Safe Mode keeps both selector tools in its allowlist, but does not bypass the server flag or credential gate. Build manifests may still carryprofileHashfor artifact consistency, and internal checkpoints may use the server-generated hash for safe recovery; neither is client-provided. - iac-code must not contain ORE TypeScript, TSX, or CSS source. It may contain only the obfuscated browser bundle, its manifest, and third-party notices. When updating the bundle, also update the manifest/hash, contract fixtures, E2E cases, and the frontend cache-busting token and tests.
- Orchestration and integration protocols:
pipeline/— multi-step IaC pipeline engine (engine/) and the selling flow (selling/: candidate generation, cost estimation, andros_deploydeployment orchestration). Selling-flow steps support per-surfacesurface_overridesinpipeline.yaml(prompt file, injected tools, conclusion schema) — for example thea2aanda2a_richvariants ofconfirm_and_select; keep rich candidate presentation scoped to Skill/A2A surfaces so REPL/Web behavior stays unchanged.a2a/— A2A 1.0 server and client with multiple transports (transports/: gRPC, stdio, unix socket, Redis streams), plus input-required permission coordination (input_required.py) and request-scoped overrides such as the caller's preferred language (runtime_overrides.py).acp/— ACP server.mcp/— MCP client integration and configuration.
- Supporting modules:
i18n/— translation infrastructure and compiledlocales/.state/,tasks/,types/,utils/— shared app state, background task management, shared type definitions, and common utilities.
- For behavioral changes, prioritize adding or updating pytest cases under
tests/. - Tests must not depend on real LLMs, real Alibaba Cloud accounts, real network calls, or local user configuration.
- When testing environment variables and credential reading, use
tmp_path,patch.dict, or mocks to isolate state. - For small changes, run at least the relevant tests; after changes to shared logic, CLI, providers, credentials, or tool execution paths, run
make testandmake lintif necessary. - Tests must pass across the full Python matrix (3.10–3.14). Keep code cross-platform: CI also runs on Windows, so watch for path-separator assumptions, binary-vs-text file I/O,
expanduserreadingUSERPROFILEon Windows, and subprocess encoding (decode Node/other subprocess output withencoding="utf-8"). tests/resource_selector/contains offline selector contracts and must not require network access or real cloud credentials.tests/resource_selector_live/is reserved for explicit, read-only real-cloud checks markedresource_selector_live; ordinary offline test runs must exclude them.
- Keep Desktop changes limited to behavior required by the installed application. Reuse the existing Python services, Web UI, sessions, settings, credentials, and pipeline logic; do not duplicate or opportunistically redesign the Web product.
- Desktop packages must be built natively on their target operating system. The sidecar build uses CPython 3.12; release builders also require Node.js 22 and stable Rust.
- The supported release artifacts are macOS Apple Silicon DMG/updater bundles, Windows x64 NSIS setup/updater bundles, and Linux x64 AppImage and deb packages. In-app updates are supported for macOS, Windows, and AppImage; deb users install a newer package through their normal package workflow.
- Treat the OS publisher signature and the Tauri updater signature as separate concerns. Unsigned/ad-hoc-signed installers may trigger platform warnings, while updater payloads must still use the configured persistent updater signing key.
- Never commit signing keys, passwords, certificates, platform credentials, or generated Desktop artifacts such as
desktop/dist/, Cargotarget/, DMG, EXE, AppImage, deb, updater archives, checksums, or SBOM output. - When Desktop behavior changes, run the relevant Python and Rust tests above. Run packaging only on the affected native platform when the change touches bundling, resources, menus, icons, sidecars, installers, or updater behavior.
- A Desktop pull request that changes only shared integration files under
src/ortests/must carry thedesktoplabel. The Desktop workflow uses that label to force the scope audit; changes to Desktop-owned paths enforce the audit automatically. Ordinary non-Desktop pull requests remain outside this boundary.
- The runtime configuration directory defaults to
~/.iac-code/, containing.credentials.yml,.cloud-credentials.yml,settings.yml,.multimodal-cache.yml, and input history (.input_history). Override by settingIAC_CODE_CONFIG_DIR(supports~and$VARexpansion); all subdirectories (projects/,image-cache/,tool-results/,logs/,memory/,a2a/,telemetry/,skills/,state/,tasks/) follow. IAC_CODE_INSTRUCTION_MEMORY_FILEselects which project instruction/memory file is loaded (e.g.make run/make devset it toIAC-CODE.md).- Dependency installs resolve through the Aliyun PyPI mirror configured under
[tool.uv]inpyproject.toml. - Do not commit, print, or hard-code real API keys, AccessKeys, Secrets, tokens, cookies, or user configuration file contents.
- Alibaba Cloud credential-related tests must use fake values and avoid triggering real cloud APIs.
- Translations span two Babel domains, and
make translateextracts/updates/compiles both across thezh es fr de ja ptlocales:messages— Python strings marked with_()ortranslate_message().webui— frontend strings extracted from the Web app JS (babel_webui.cfg, which excludesvendor/).
- Python (
messages) domain: do not use an f-string with_()(e.g.f"hello {_('world')}"); Python 3.10's tokenizer treats the entire f-string as a single token so Babel cannot extract nested_()calls — usestr.formatinstead (e.g._('hello {}').format(name)). _()resolves against the process-wide locale and serves text displayed on the local machine (REPL, Web UI, local errors). Text that the A2A server returns in the caller's requested language must usei18n.translate_message(msgid, language=...), which resolves the English msgid from themessagescatalog per request, so concurrent tasks with differentpreferredLanguagevalues do not fight over the global locale. Do not nest the two, and keep the msgid a plain string literal as the first argument so Babel can extract it (translate_messageis registered as an extraction keyword inbabel.cfg).- Web (
webui) domain: a new frontendt()entry must exist and be non-empty in all locales (there is a strict catalog-completeness test). Frontend JS modules are cache-busted with per-module?v=tokens — changing a module means bumping its token inindex.htmland keepingtests/web/test_frontend_static.pyin sync. - After modifying user-facing translatable strings (Python or frontend), run
make translate. Compiled.mofiles are build artifacts and are not committed — but a missing.momakes the UI silently fall back to English, so ensure compilation succeeds locally. - Public Desktop documentation is maintained in English, Simplified Chinese, Spanish, French, German, Japanese, and Portuguese. A Desktop documentation change must update
README.md, every matching file inreadme/, and every matching website document underwebsite/docs/andwebsite/i18n/. Write natural translations; do not use English copies or placeholder translations. The website locale name for Simplified Chinese iszh-Hans. - Markdown files and scripts under
src/iac_code/skills/bundled/iac_aliyun/are bundled skill resources; when modifying them, maintain consistency between templates, parameter descriptions, and conversion scripts. - Do not commit generated translations, build artifacts, or coverage outputs unless the current task explicitly requires it.
- The workspace may contain changes from others; do not revert changes you did not make.
- Do not use
git reset --hard, force push, or other destructive operations unless the user explicitly requests it. - Before committing, verify that
git statusonly includes files related to the current task.