iac-code 0.8.0__tar.gz → 0.9.1__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.
Files changed (496) hide show
  1. {iac_code-0.8.0 → iac_code-0.9.1}/PKG-INFO +1 -1
  2. {iac_code-0.8.0 → iac_code-0.9.1}/setup.py +48 -4
  3. iac_code-0.9.1/src/iac_code/__init__.py +2 -0
  4. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/artifacts.py +134 -38
  5. iac_code-0.9.1/src/iac_code/a2a/backup.py +91 -0
  6. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/events.py +14 -5
  7. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/executor.py +246 -29
  8. iac_code-0.9.1/src/iac_code/a2a/metadata_redaction.py +85 -0
  9. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/metrics.py +21 -0
  10. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/pipeline_events.py +55 -2
  11. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/pipeline_executor.py +1889 -164
  12. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/pipeline_journal.py +152 -34
  13. iac_code-0.9.1/src/iac_code/a2a/pipeline_paths.py +69 -0
  14. iac_code-0.9.1/src/iac_code/a2a/pipeline_performance.py +14 -0
  15. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/pipeline_recovery.py +6 -0
  16. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/pipeline_snapshot.py +277 -12
  17. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/pipeline_stream.py +447 -25
  18. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/task_store.py +130 -25
  19. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/dispatcher.py +47 -2
  20. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/convert.py +11 -4
  21. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/session.py +45 -7
  22. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/agent/agent_loop.py +251 -13
  23. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/agent/agent_tool.py +1 -0
  24. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/agent/message.py +1 -0
  25. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/agent/system_prompt.py +35 -8
  26. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/cli/headless.py +92 -0
  27. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/cli/main.py +61 -0
  28. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/cli/output_formats.py +48 -10
  29. iac_code-0.9.1/src/iac_code/cli/process_events.py +56 -0
  30. iac_code-0.9.1/src/iac_code/cli/process_mode.py +1084 -0
  31. iac_code-0.9.1/src/iac_code/cli/process_protocol.py +282 -0
  32. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/__init__.py +10 -0
  33. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/auth.py +7 -1
  34. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/memory.py +14 -0
  35. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/resume.py +6 -1
  36. iac_code-0.9.1/src/iac_code/commands/thinking_enabled.py +117 -0
  37. iac_code-0.9.1/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.mo +0 -0
  38. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.po +1146 -118
  39. iac_code-0.9.1/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.mo +0 -0
  40. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.po +1140 -120
  41. iac_code-0.9.1/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.mo +0 -0
  42. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.po +1152 -118
  43. iac_code-0.9.1/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
  44. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.po +1081 -118
  45. iac_code-0.9.1/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.mo +0 -0
  46. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.po +1130 -121
  47. iac_code-0.9.1/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.mo +0 -0
  48. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.po +1068 -123
  49. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/output.py +19 -9
  50. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/tools.py +14 -2
  51. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/__init__.py +23 -0
  52. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/display_names.py +6 -0
  53. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_graph.py +4241 -0
  54. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_meta.py +213 -0
  55. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_metas/Categories.json +659 -0
  56. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_metas/config.json +107776 -0
  57. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_metas/products.json +1432 -0
  58. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_resource_inventory.py +299 -0
  59. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_rule_candidates.py +690 -0
  60. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_rule_drafts.py +579 -0
  61. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_rule_facts.py +241 -0
  62. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_rules.json +2606 -0
  63. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_rules.py +465 -0
  64. iac_code-0.9.1/src/iac_code/pipeline/engine/architecture_semantic_planning.py +5193 -0
  65. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/ask_user_question_tool.py +9 -0
  66. iac_code-0.9.1/src/iac_code/pipeline/engine/complete_step_tool.py +1131 -0
  67. iac_code-0.9.1/src/iac_code/pipeline/engine/completion_guard_state.py +129 -0
  68. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/display_replay.py +169 -1
  69. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/events.py +18 -0
  70. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/interrupt.py +12 -4
  71. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/loader.py +81 -2
  72. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/observability.py +52 -0
  73. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/pipeline_runner.py +668 -74
  74. iac_code-0.9.1/src/iac_code/pipeline/engine/prerequisites.py +1801 -0
  75. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/prompts/interrupt_judge.md +5 -3
  76. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/recovery.py +18 -1
  77. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/session.py +102 -4
  78. iac_code-0.9.1/src/iac_code/pipeline/engine/show_diagram_tool.py +290 -0
  79. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/step_executor.py +160 -32
  80. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/step_spec.py +48 -14
  81. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/sub_pipeline_executor.py +128 -19
  82. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/transcript_storage.py +78 -31
  83. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/hooks/deploying.py +53 -0
  84. iac_code-0.9.1/src/iac_code/pipeline/selling/pipeline.yaml +513 -0
  85. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/confirm_and_select.md +14 -6
  86. iac_code-0.9.1/src/iac_code/pipeline/selling/prompts/cost_estimating.md +28 -0
  87. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/deploying.md +10 -4
  88. iac_code-0.9.1/src/iac_code/pipeline/selling/prompts/reviewing.md +63 -0
  89. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/template_generating.md +5 -3
  90. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/template-parameter-recommendation.md +24 -31
  91. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-cost/SKILL.md +60 -32
  92. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-cost/evals.json +26 -23
  93. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/template-parameter-recommendation.md +24 -31
  94. iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying/SKILL.md +161 -0
  95. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying/evals.json +57 -20
  96. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying/references/template-parameter-recommendation.md +24 -31
  97. iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-review/SKILL.md +140 -0
  98. iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-review/evals.json +284 -0
  99. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating/SKILL.md +2 -2
  100. iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating/references/template-parameter-recommendation.md +158 -0
  101. iac_code-0.9.1/src/iac_code/pipeline/selling/tools/__init__.py +3 -0
  102. iac_code-0.9.1/src/iac_code/pipeline/selling/tools/infraguard_scan_tool.py +810 -0
  103. iac_code-0.9.1/src/iac_code/pipeline/selling/tools/ros_deploy_tool.py +706 -0
  104. iac_code-0.9.1/src/iac_code/pipeline/selling/tools/ros_template_tools.py +17 -0
  105. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/dashscope_provider.py +58 -20
  106. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/manager.py +32 -2
  107. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/agent_factory.py +193 -16
  108. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/permissions/audit.py +47 -3
  109. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/permissions/loader.py +1 -0
  110. iac_code-0.9.1/src/iac_code/services/permissions/trusted_roots.py +45 -0
  111. iac_code-0.9.1/src/iac_code/services/session_backup.py +1183 -0
  112. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/session_index.py +128 -22
  113. iac_code-0.9.1/src/iac_code/services/session_layout.py +203 -0
  114. iac_code-0.9.1/src/iac_code/services/session_metadata.py +139 -0
  115. iac_code-0.9.1/src/iac_code/services/session_storage.py +995 -0
  116. iac_code-0.9.1/src/iac_code/services/session_usage.py +320 -0
  117. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/content_serializer.py +16 -4
  118. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/metrics.py +3 -0
  119. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/names.py +6 -0
  120. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/ecs.md +167 -0
  121. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/oss.md +69 -0
  122. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/rds.md +95 -0
  123. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/redis.md +100 -0
  124. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/slb.md +60 -0
  125. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/vpc.md +54 -0
  126. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/ros-template.md +155 -0
  127. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/template-parameters.md +206 -0
  128. iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun/references/terraform-template.md +101 -0
  129. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/pac_aliyun/SKILL.md +9 -1
  130. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/pac_aliyun/references/infraguard-policy-generation.md +42 -8
  131. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/processor.py +11 -1
  132. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/skill_tool.py +1 -0
  133. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/state/app_state.py +1 -0
  134. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/base.py +23 -1
  135. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/path_validation.py +5 -1
  136. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/permissions.py +2 -0
  137. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/aliyun_api.py +38 -4
  138. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/hooks/ros_validate.py +61 -0
  139. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/ros_stack.py +81 -9
  140. iac_code-0.9.1/src/iac_code/tools/cloud/aliyun/ros_template_tools.py +343 -0
  141. iac_code-0.9.1/src/iac_code/tools/cloud/aliyun/template_source.py +181 -0
  142. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/base_api.py +9 -1
  143. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/base_stack.py +55 -3
  144. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/registry.py +4 -0
  145. iac_code-0.9.1/src/iac_code/tools/glob.py +290 -0
  146. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/grep.py +56 -8
  147. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/list_files.py +10 -5
  148. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/path_safety.py +80 -6
  149. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/read_file.py +10 -10
  150. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/result_storage.py +19 -4
  151. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/tool_executor.py +28 -8
  152. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/types/permissions.py +8 -0
  153. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/types/stream_events.py +11 -0
  154. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/candidate_selection.py +150 -21
  155. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/select.py +4 -6
  156. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/in_place_render.py +3 -1
  157. iac_code-0.9.1/src/iac_code/ui/diagram_rendering.py +57 -0
  158. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/pipeline_display_replay.py +44 -1
  159. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/renderer.py +166 -11
  160. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/repl.py +813 -32
  161. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/stream_accumulator.py +27 -0
  162. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/transcript_view.py +26 -2
  163. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/image/store.py +72 -32
  164. iac_code-0.9.1/src/iac_code/utils/path_components.py +26 -0
  165. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/project_paths.py +29 -1
  166. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/public_errors.py +28 -11
  167. iac_code-0.9.1/src/iac_code/utils/public_paths.py +234 -0
  168. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/state_io.py +205 -13
  169. iac_code-0.9.1/src/iac_code/utils/tool_result_redaction.py +93 -0
  170. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code.egg-info/PKG-INFO +1 -1
  171. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code.egg-info/SOURCES.txt +40 -0
  172. iac_code-0.8.0/src/iac_code/__init__.py +0 -2
  173. iac_code-0.8.0/src/iac_code/a2a/metadata_redaction.py +0 -62
  174. iac_code-0.8.0/src/iac_code/a2a/pipeline_paths.py +0 -29
  175. iac_code-0.8.0/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.mo +0 -0
  176. iac_code-0.8.0/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.mo +0 -0
  177. iac_code-0.8.0/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.mo +0 -0
  178. iac_code-0.8.0/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
  179. iac_code-0.8.0/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.mo +0 -0
  180. iac_code-0.8.0/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.mo +0 -0
  181. iac_code-0.8.0/src/iac_code/pipeline/engine/complete_step_tool.py +0 -566
  182. iac_code-0.8.0/src/iac_code/pipeline/engine/completion_guard_state.py +0 -83
  183. iac_code-0.8.0/src/iac_code/pipeline/engine/show_diagram_tool.py +0 -354
  184. iac_code-0.8.0/src/iac_code/pipeline/selling/pipeline.yaml +0 -268
  185. iac_code-0.8.0/src/iac_code/pipeline/selling/prompts/cost_estimating.md +0 -18
  186. iac_code-0.8.0/src/iac_code/pipeline/selling/prompts/reviewing.md +0 -19
  187. iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying/SKILL.md +0 -145
  188. iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-review/SKILL.md +0 -76
  189. iac_code-0.8.0/src/iac_code/services/permissions/trusted_roots.py +0 -21
  190. iac_code-0.8.0/src/iac_code/services/session_metadata.py +0 -78
  191. iac_code-0.8.0/src/iac_code/services/session_storage.py +0 -406
  192. iac_code-0.8.0/src/iac_code/services/session_usage.py +0 -176
  193. iac_code-0.8.0/src/iac_code/tools/cloud/aliyun/template_source.py +0 -17
  194. iac_code-0.8.0/src/iac_code/tools/glob.py +0 -160
  195. iac_code-0.8.0/src/iac_code/utils/image/__init__.py +0 -0
  196. {iac_code-0.8.0 → iac_code-0.9.1}/LICENSE +0 -0
  197. {iac_code-0.8.0 → iac_code-0.9.1}/MANIFEST.in +0 -0
  198. {iac_code-0.8.0 → iac_code-0.9.1}/README.md +0 -0
  199. {iac_code-0.8.0 → iac_code-0.9.1}/pyproject.toml +0 -0
  200. {iac_code-0.8.0 → iac_code-0.9.1}/setup.cfg +0 -0
  201. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/__init__.py +0 -0
  202. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/agent_card.py +0 -0
  203. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/app.py +0 -0
  204. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/client.py +0 -0
  205. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/exposure.py +0 -0
  206. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/jsonrpc_passthrough.py +0 -0
  207. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/parts.py +0 -0
  208. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/persistence.py +0 -0
  209. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/push.py +0 -0
  210. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/push_queue.py +0 -0
  211. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/push_secrets.py +0 -0
  212. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/push_worker.py +0 -0
  213. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/router.py +0 -0
  214. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/runtime_overrides.py +0 -0
  215. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/signing.py +0 -0
  216. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/thinking_metadata.py +0 -0
  217. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transport.py +0 -0
  218. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/__init__.py +0 -0
  219. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/base.py +0 -0
  220. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/grpc.py +0 -0
  221. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/grpc_jsonrpc.py +0 -0
  222. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/http.py +0 -0
  223. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/redis_streams.py +0 -0
  224. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/stdio.py +0 -0
  225. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/unix.py +0 -0
  226. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/transports/websocket.py +0 -0
  227. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/a2a/types.py +0 -0
  228. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/__init__.py +0 -0
  229. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/http_sse.py +0 -0
  230. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/mcp.py +0 -0
  231. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/metrics.py +0 -0
  232. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/server.py +0 -0
  233. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/slash_registry.py +0 -0
  234. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/state.py +0 -0
  235. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/tools.py +0 -0
  236. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/types.py +0 -0
  237. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/acp/version.py +0 -0
  238. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/agent/__init__.py +0 -0
  239. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/agent/agent_types.py +0 -0
  240. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/cli/__init__.py +0 -0
  241. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/cli/install_git_bash.py +0 -0
  242. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/cli/update.py +0 -0
  243. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/clear.py +0 -0
  244. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/compact.py +0 -0
  245. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/debug.py +0 -0
  246. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/effort.py +0 -0
  247. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/exit.py +0 -0
  248. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/help.py +0 -0
  249. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/model.py +0 -0
  250. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/prompt.py +0 -0
  251. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/registry.py +0 -0
  252. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/rename.py +0 -0
  253. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/skills.py +0 -0
  254. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/status.py +0 -0
  255. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/commands/tasks.py +0 -0
  256. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/config.py +0 -0
  257. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/i18n/__init__.py +0 -0
  258. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/__init__.py +0 -0
  259. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/cli.py +0 -0
  260. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/client.py +0 -0
  261. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/config.py +0 -0
  262. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/env_expansion.py +0 -0
  263. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/errors.py +0 -0
  264. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/manager.py +0 -0
  265. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/oauth.py +0 -0
  266. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/prompts.py +0 -0
  267. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/skills.py +0 -0
  268. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/storage.py +0 -0
  269. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/mcp/types.py +0 -0
  270. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/memory/__init__.py +0 -0
  271. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/memory/memory_manager.py +0 -0
  272. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/memory/memory_tools.py +0 -0
  273. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/memory/project_memory.py +0 -0
  274. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/memory/recall.py +0 -0
  275. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/config.py +0 -0
  276. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/constants.py +0 -0
  277. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/__init__.py +0 -0
  278. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/cleanup.py +0 -0
  279. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/context.py +0 -0
  280. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/handoff.py +0 -0
  281. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/public_errors.py +0 -0
  282. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/resume_recovery.py +0 -0
  283. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/state_machine.py +0 -0
  284. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/types.py +0 -0
  285. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/ui_contract.py +0 -0
  286. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/engine/user_input.py +0 -0
  287. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/architecture_planning.md +0 -0
  288. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/confirm_and_select.a2a.md +0 -0
  289. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/evaluate_candidates.md +0 -0
  290. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/prompts/intent_parsing.md +0 -0
  291. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/cloud-products/ecs.md +0 -0
  292. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/cloud-products/oss.md +0 -0
  293. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/cloud-products/rds.md +0 -0
  294. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/cloud-products/redis.md +0 -0
  295. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/cloud-products/slb.md +0 -0
  296. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/cloud-products/vpc.md +0 -0
  297. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/ros-template.md +0 -0
  298. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/template-parameters.md +0 -0
  299. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/pipeline/selling}/references/terraform-template.md +0 -0
  300. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-architecture/SKILL.md +0 -0
  301. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-architecture/evals.json +0 -0
  302. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/cloud-products/ecs.md +0 -0
  303. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/cloud-products/oss.md +0 -0
  304. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/cloud-products/rds.md +0 -0
  305. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/cloud-products/redis.md +0 -0
  306. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/cloud-products/slb.md +0 -0
  307. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/cloud-products/vpc.md +0 -0
  308. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/ros-template.md +0 -0
  309. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/template-parameters.md +0 -0
  310. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-cost}/references/terraform-template.md +0 -0
  311. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/cloud-products/ecs.md +0 -0
  312. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/cloud-products/oss.md +0 -0
  313. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/cloud-products/rds.md +0 -0
  314. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/cloud-products/redis.md +0 -0
  315. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/cloud-products/slb.md +0 -0
  316. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/cloud-products/vpc.md +0 -0
  317. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/ros-template.md +0 -0
  318. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/template-parameters.md +0 -0
  319. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-deploying}/references/terraform-template.md +0 -0
  320. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-intent/SKILL.md +0 -0
  321. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-intent/evals.json +0 -0
  322. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating/evals.json +0 -0
  323. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/cloud-products/ecs.md +0 -0
  324. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/cloud-products/oss.md +0 -0
  325. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/cloud-products/rds.md +0 -0
  326. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/cloud-products/redis.md +0 -0
  327. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/cloud-products/slb.md +0 -0
  328. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/cloud-products/vpc.md +0 -0
  329. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/ros-template.md +0 -0
  330. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/template-parameters.md +0 -0
  331. {iac_code-0.8.0/src/iac_code/skills/bundled/iac_aliyun → iac_code-0.9.1/src/iac_code/pipeline/selling/skills/iac-aliyun-template-generating}/references/terraform-template.md +0 -0
  332. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/pipeline/selling/tools/show_candidate_detail_tool.py +0 -0
  333. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/__init__.py +0 -0
  334. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/anthropic_provider.py +0 -0
  335. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/azure_openai_provider.py +0 -0
  336. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/base.py +0 -0
  337. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/deepseek_provider.py +0 -0
  338. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/gemini_provider.py +0 -0
  339. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/kimi_provider.py +0 -0
  340. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/lmstudio_provider.py +0 -0
  341. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/minimax_provider.py +0 -0
  342. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/modelscope_provider.py +0 -0
  343. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/ollama_provider.py +0 -0
  344. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/openai_provider.py +0 -0
  345. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/openrouter_provider.py +0 -0
  346. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/registry.py +0 -0
  347. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/request_logging.py +0 -0
  348. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/request_policy.py +0 -0
  349. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/retry.py +0 -0
  350. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/siliconflow_provider.py +0 -0
  351. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/stream_watchdog.py +0 -0
  352. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/thinking.py +0 -0
  353. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/volcengine_provider.py +0 -0
  354. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/providers/zhipu_provider.py +0 -0
  355. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/__init__.py +0 -0
  356. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/capabilities/__init__.py +0 -0
  357. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/capabilities/auto_detect.py +0 -0
  358. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/capabilities/multimodal.py +0 -0
  359. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/cloud_credentials.py +0 -0
  360. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/context_manager.py +0 -0
  361. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/permissions/__init__.py +0 -0
  362. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/permissions/pipeline.py +0 -0
  363. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/permissions/rule_scope.py +0 -0
  364. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/permissions/storage.py +0 -0
  365. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/providers/__init__.py +0 -0
  366. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/providers/aliyun.py +0 -0
  367. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/providers/aliyun_oauth.py +0 -0
  368. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/qwenpaw_source.py +0 -0
  369. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/session_resolver.py +0 -0
  370. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/__init__.py +0 -0
  371. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/attributes.py +0 -0
  372. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/client.py +0 -0
  373. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/config.py +0 -0
  374. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/constants.py +0 -0
  375. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/events.py +0 -0
  376. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/fallback.py +0 -0
  377. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/identity.py +0 -0
  378. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/sanitize.py +0 -0
  379. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/sink.py +0 -0
  380. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/tracing.py +0 -0
  381. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/telemetry/types.py +0 -0
  382. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/token_budget.py +0 -0
  383. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/token_counter.py +0 -0
  384. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/services/update_checker.py +0 -0
  385. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/__init__.py +0 -0
  386. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/auto_trigger.py +0 -0
  387. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/__init__.py +0 -0
  388. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/iac_aliyun/SKILL.md +0 -0
  389. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/iac_aliyun/__init__.py +0 -0
  390. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/iac_aliyun/auto_trigger.py +0 -0
  391. {iac_code-0.8.0/src/iac_code/pipeline/selling/skills/iac-aliyun-cost → iac_code-0.9.1/src/iac_code/skills/bundled/iac_aliyun}/references/template-parameter-recommendation.md +0 -0
  392. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/iac_aliyun/scripts/tf2ros.py +0 -0
  393. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/pac_aliyun/__init__.py +0 -0
  394. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/pac_aliyun/auto_trigger.py +0 -0
  395. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/bundled/simplify.py +0 -0
  396. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/discovery.py +0 -0
  397. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/frontmatter.py +0 -0
  398. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/listing.py +0 -0
  399. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/loader.py +0 -0
  400. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/management.py +0 -0
  401. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/renderer.py +0 -0
  402. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/settings.py +0 -0
  403. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/skills/skill_definition.py +0 -0
  404. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/state/__init__.py +0 -0
  405. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tasks/__init__.py +0 -0
  406. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tasks/notification_queue.py +0 -0
  407. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tasks/task_state.py +0 -0
  408. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tasks/task_tools.py +0 -0
  409. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/__init__.py +0 -0
  410. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/__init__.py +0 -0
  411. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/argv_safety.py +0 -0
  412. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/bash_tool.py +0 -0
  413. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/command_parser.py +0 -0
  414. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/mode_validation.py +0 -0
  415. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/readonly_commands.py +0 -0
  416. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/rule_matching.py +0 -0
  417. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/bash/safety_checks.py +0 -0
  418. {iac_code-0.8.0/src/iac_code/pipeline/selling/tools → iac_code-0.9.1/src/iac_code/tools/cloud}/__init__.py +0 -0
  419. {iac_code-0.8.0/src/iac_code/tools/cloud → iac_code-0.9.1/src/iac_code/tools/cloud/aliyun}/__init__.py +0 -0
  420. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/aliyun_doc_search.py +0 -0
  421. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/api_hooks.py +0 -0
  422. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/endpoints.yml +0 -0
  423. {iac_code-0.8.0/src/iac_code/tools/cloud/aliyun → iac_code-0.9.1/src/iac_code/tools/cloud/aliyun/hooks}/__init__.py +0 -0
  424. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/hooks/ros_parameters.py +0 -0
  425. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/ros_client.py +0 -0
  426. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/ros_stack_instances.py +0 -0
  427. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/ros_yaml.py +0 -0
  428. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/aliyun/user_agent.py +0 -0
  429. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/cloud/types.py +0 -0
  430. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/edit_file.py +0 -0
  431. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/web_fetch.py +0 -0
  432. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/tools/write_file.py +0 -0
  433. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/types/__init__.py +0 -0
  434. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/types/skill_source.py +0 -0
  435. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/__init__.py +0 -0
  436. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/banner.py +0 -0
  437. {iac_code-0.8.0/src/iac_code/tools/cloud/aliyun/hooks → iac_code-0.9.1/src/iac_code/ui/components}/__init__.py +0 -0
  438. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/dialog.py +0 -0
  439. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/divider.py +0 -0
  440. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/fuzzy_picker.py +0 -0
  441. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/parallel_tabs.py +0 -0
  442. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/progress_bar.py +0 -0
  443. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/search_box.py +0 -0
  444. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/status_icon.py +0 -0
  445. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/components/tabs.py +0 -0
  446. {iac_code-0.8.0/src/iac_code/ui/components → iac_code-0.9.1/src/iac_code/ui/core}/__init__.py +0 -0
  447. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/input_history.py +0 -0
  448. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/key_event.py +0 -0
  449. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/prompt_input.py +0 -0
  450. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/raw_input.py +0 -0
  451. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/raw_input_win.py +0 -0
  452. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/core/screen.py +0 -0
  453. {iac_code-0.8.0/src/iac_code/ui/core → iac_code-0.9.1/src/iac_code/ui/dialogs}/__init__.py +0 -0
  454. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/global_search.py +0 -0
  455. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/history_search.py +0 -0
  456. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/memory.py +0 -0
  457. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/memory_editor.py +0 -0
  458. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/model_picker.py +0 -0
  459. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/quick_open.py +0 -0
  460. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/resume_picker.py +0 -0
  461. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/dialogs/skills_picker.py +0 -0
  462. {iac_code-0.8.0/src/iac_code/ui/dialogs → iac_code-0.9.1/src/iac_code/ui/keybindings}/__init__.py +0 -0
  463. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/keybindings/manager.py +0 -0
  464. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/pipeline_styles.py +0 -0
  465. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/spinner.py +0 -0
  466. {iac_code-0.8.0/src/iac_code/ui/keybindings → iac_code-0.9.1/src/iac_code/ui/suggestions}/__init__.py +0 -0
  467. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/aggregator.py +0 -0
  468. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/command_provider.py +0 -0
  469. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/directory_provider.py +0 -0
  470. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/file_provider.py +0 -0
  471. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/shell_history_provider.py +0 -0
  472. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/skill_provider.py +0 -0
  473. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/token_extractor.py +0 -0
  474. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/ui/suggestions/types.py +0 -0
  475. {iac_code-0.8.0/src/iac_code/ui/suggestions → iac_code-0.9.1/src/iac_code/utils}/__init__.py +0 -0
  476. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/background_housekeeping.py +0 -0
  477. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/cleanup.py +0 -0
  478. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/console.py +0 -0
  479. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/file_security.py +0 -0
  480. {iac_code-0.8.0/src/iac_code/utils → iac_code-0.9.1/src/iac_code/utils/image}/__init__.py +0 -0
  481. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/image/clipboard.py +0 -0
  482. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/image/format_detect.py +0 -0
  483. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/image/pasted_content.py +0 -0
  484. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/image/processor.py +0 -0
  485. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/image/resizer.py +0 -0
  486. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/json_utils.py +0 -0
  487. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/log.py +0 -0
  488. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/path_locks.py +0 -0
  489. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/platform.py +0 -0
  490. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/signals.py +0 -0
  491. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/tool_input_parser.py +0 -0
  492. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code/utils/windows_paths.py +0 -0
  493. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code.egg-info/dependency_links.txt +0 -0
  494. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code.egg-info/entry_points.txt +0 -0
  495. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code.egg-info/requires.txt +0 -0
  496. {iac_code-0.8.0 → iac_code-0.9.1}/src/iac_code.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iac_code
3
- Version: 0.8.0
3
+ Version: 0.9.1
4
4
  Summary: Your AI-powered Infrastructure as Code assistant
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -15,7 +15,7 @@ from setuptools.command.sdist import sdist
15
15
  INIT_PATH = Path("src/iac_code/__init__.py")
16
16
  LOCALES_DIR = Path("src/iac_code/i18n/locales")
17
17
  PROJECT_ROOT = Path(__file__).resolve().parent
18
- IAC_ALIYUN_REFERENCES_DIR = PROJECT_ROOT / "src/iac_code/skills/bundled/iac_aliyun/references"
18
+ SELLING_REFERENCES_DIR = PROJECT_ROOT / "src/iac_code/pipeline/selling/references"
19
19
  SELLING_IAC_ALIYUN_SKILLS = (
20
20
  "iac-aliyun-template-generating",
21
21
  "iac-aliyun-cost",
@@ -207,10 +207,54 @@ def _replace_release_date():
207
207
  INIT_PATH.write_text(content, encoding="utf-8")
208
208
 
209
209
 
210
+ def _git_symlink_placeholder_target(path: Path) -> Path | None:
211
+ """Return the target for a Windows core.symlinks=false placeholder file."""
212
+ if path.is_symlink() or not path.is_file():
213
+ return None
214
+ try:
215
+ if path.stat().st_size > 4096:
216
+ return None
217
+ raw_target = path.read_text(encoding="utf-8")
218
+ except (OSError, UnicodeDecodeError):
219
+ return None
220
+ if not raw_target or "\n" in raw_target or "\r" in raw_target:
221
+ return None
222
+ target = Path(raw_target)
223
+ if not target.is_absolute():
224
+ target = path.parent / target
225
+ try:
226
+ return target.resolve(strict=True)
227
+ except OSError:
228
+ return None
229
+
230
+
231
+ def _copy_reference_entry(source: Path, target: Path) -> None:
232
+ placeholder_target = _git_symlink_placeholder_target(source)
233
+ if placeholder_target is not None:
234
+ source = placeholder_target
235
+ elif source.is_symlink():
236
+ source = source.resolve(strict=True)
237
+
238
+ if source.is_dir():
239
+ target.mkdir(parents=True, exist_ok=True)
240
+ for child in source.iterdir():
241
+ _copy_reference_entry(child, target / child.name)
242
+ return
243
+
244
+ target.parent.mkdir(parents=True, exist_ok=True)
245
+ shutil.copy2(source, target)
246
+
247
+
248
+ def _copy_reference_tree(source: Path, target: Path) -> None:
249
+ target.mkdir(parents=True, exist_ok=True)
250
+ for child in source.iterdir():
251
+ _copy_reference_entry(child, target / child.name)
252
+
253
+
210
254
  def _copy_selling_skill_references_to_package_root(package_root) -> None:
211
255
  """Expand selling-skill reference symlinks into real dirs under an iac_code package root."""
212
- if not IAC_ALIYUN_REFERENCES_DIR.is_dir():
213
- raise RuntimeError("references directory not found: %s" % IAC_ALIYUN_REFERENCES_DIR)
256
+ if not SELLING_REFERENCES_DIR.is_dir():
257
+ raise RuntimeError("references directory not found: %s" % SELLING_REFERENCES_DIR)
214
258
 
215
259
  package_root = Path(package_root)
216
260
  for skill_name in SELLING_IAC_ALIYUN_SKILLS:
@@ -220,7 +264,7 @@ def _copy_selling_skill_references_to_package_root(package_root) -> None:
220
264
  elif target.exists():
221
265
  shutil.rmtree(target)
222
266
  target.parent.mkdir(parents=True, exist_ok=True)
223
- shutil.copytree(IAC_ALIYUN_REFERENCES_DIR, target)
267
+ _copy_reference_tree(SELLING_REFERENCES_DIR, target)
224
268
 
225
269
 
226
270
  def _copy_selling_skill_references(build_lib: str) -> None:
@@ -0,0 +1,2 @@
1
+ __version__ = "0.9.1"
2
+ __release_date__ = "2026-07-10"
@@ -6,13 +6,28 @@ import ntpath
6
6
  import os
7
7
  import re
8
8
  import uuid
9
+ from collections.abc import Iterable, Mapping
9
10
  from dataclasses import asdict, dataclass
10
11
  from pathlib import Path
11
12
  from typing import Any
12
13
  from urllib.parse import quote, unquote, urlsplit
13
14
 
14
15
  from iac_code.i18n import _
16
+ from iac_code.services.session_layout import (
17
+ SESSION_LAYOUT_VERSION_V2,
18
+ SessionPaths,
19
+ UnsupportedSessionLayoutError,
20
+ ensure_session_owned_dir,
21
+ require_supported_session_layout,
22
+ )
15
23
  from iac_code.utils.public_errors import sanitize_public_text
24
+ from iac_code.utils.public_paths import relativize_public_file_uri
25
+ from iac_code.utils.state_io import atomic_write_bytes
26
+ from iac_code.utils.tool_result_redaction import (
27
+ REDACTED_TOOL_RESULT_VALUE,
28
+ is_file_content_key,
29
+ redact_file_content_from_json_string,
30
+ )
16
31
 
17
32
  PUBLIC_ARTIFACT_URI_PREFIX = "iac-code-artifact://"
18
33
  _PUBLIC_ARTIFACT_URI_SCHEME = "iac-code-artifact"
@@ -104,64 +119,107 @@ def _windows_safe_filename(filename: str) -> str:
104
119
  return sanitized
105
120
 
106
121
 
107
- def sanitize_public_artifact_data(value: Any) -> Any:
122
+ def sanitize_public_artifact_data(
123
+ value: Any,
124
+ *,
125
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
126
+ ) -> Any:
108
127
  if isinstance(value, list):
109
- return [sanitize_public_artifact_data(item) for item in value]
128
+ return [sanitize_public_artifact_data(item, public_path_roots=public_path_roots) for item in value]
110
129
  if isinstance(value, tuple):
111
- return [sanitize_public_artifact_data(item) for item in value]
130
+ return [sanitize_public_artifact_data(item, public_path_roots=public_path_roots) for item in value]
112
131
  if isinstance(value, str):
113
- return _sanitize_artifact_scalar_string(value)
132
+ return _sanitize_artifact_scalar_string(value, public_path_roots=public_path_roots)
114
133
  if not isinstance(value, dict):
115
134
  return value
116
135
 
117
136
  sanitized: dict[Any, Any] = {}
118
137
  for key, raw_value in value.items():
119
138
  key_name = str(key)
139
+ output_key, key_is_public_path = _sanitize_public_mapping_key(key, public_path_roots=public_path_roots)
120
140
  if key_name.lower() in _ARTIFACT_PAYLOAD_KEYS:
121
141
  continue
122
- if _is_sensitive_output_key(key_name):
123
- sanitized[key] = "[REDACTED]"
142
+ if not key_is_public_path and _is_sensitive_output_key(key_name):
143
+ sanitized[output_key] = "[REDACTED]"
144
+ continue
145
+ if not key_is_public_path and is_file_content_key(key_name):
146
+ sanitized[output_key] = REDACTED_TOOL_RESULT_VALUE
124
147
  continue
125
148
  if _is_artifact_uri_key(key_name):
126
149
  if isinstance(raw_value, str):
127
- sanitized_value = _sanitize_artifact_string(key_name, raw_value)
150
+ sanitized_value = _sanitize_artifact_string(key_name, raw_value, public_path_roots=public_path_roots)
128
151
  if sanitized_value is not None:
129
- sanitized[key] = sanitized_value
152
+ sanitized[output_key] = sanitized_value
130
153
  continue
131
154
  if isinstance(raw_value, str):
132
- sanitized_value = _sanitize_artifact_string(key_name, raw_value)
155
+ sanitized_value = _sanitize_artifact_string(key_name, raw_value, public_path_roots=public_path_roots)
133
156
  if sanitized_value is None:
134
157
  continue
135
- sanitized[key] = sanitized_value
158
+ sanitized[output_key] = sanitized_value
136
159
  continue
137
- sanitized[key] = sanitize_public_artifact_data(raw_value)
160
+ sanitized[output_key] = sanitize_public_artifact_data(raw_value, public_path_roots=public_path_roots)
138
161
  return sanitized
139
162
 
140
163
 
141
- def sanitize_public_tool_output_data(value: Any) -> Any:
164
+ def sanitize_public_tool_output_data(
165
+ value: Any,
166
+ *,
167
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
168
+ ) -> Any:
142
169
  if isinstance(value, str):
143
- return sanitize_public_artifact_text(value, fallback_summary="")
170
+ value = redact_file_content_from_json_string(value)
171
+ return sanitize_public_artifact_text(value, fallback_summary="", public_path_roots=public_path_roots)
144
172
  if isinstance(value, list):
145
- return [sanitize_public_tool_output_data(item) for item in value]
173
+ return [sanitize_public_tool_output_data(item, public_path_roots=public_path_roots) for item in value]
146
174
  if isinstance(value, tuple):
147
- return [sanitize_public_tool_output_data(item) for item in value]
175
+ return [sanitize_public_tool_output_data(item, public_path_roots=public_path_roots) for item in value]
148
176
  if not isinstance(value, dict):
149
177
  return value
150
178
  if _looks_like_artifact_payload_dict(value):
151
- return sanitize_public_artifact_data(value)
179
+ return sanitize_public_artifact_data(value, public_path_roots=public_path_roots)
152
180
 
153
181
  sanitized: dict[Any, Any] = {}
154
182
  for key, raw_value in value.items():
155
- if str(key).lower() in _ARTIFACT_CONTAINER_KEYS:
156
- sanitized[key] = sanitize_public_artifact_data(raw_value)
157
- elif _is_sensitive_output_key(key):
158
- sanitized[key] = "[REDACTED]"
183
+ key_name = str(key)
184
+ output_key, key_is_public_path = _sanitize_public_mapping_key(key, public_path_roots=public_path_roots)
185
+ if key_name.lower() in _ARTIFACT_CONTAINER_KEYS:
186
+ sanitized[output_key] = sanitize_public_artifact_data(raw_value, public_path_roots=public_path_roots)
187
+ elif not key_is_public_path and _is_sensitive_output_key(key_name):
188
+ sanitized[output_key] = "[REDACTED]"
189
+ elif not key_is_public_path and is_file_content_key(key_name):
190
+ sanitized[output_key] = REDACTED_TOOL_RESULT_VALUE
159
191
  else:
160
- sanitized[key] = sanitize_public_tool_output_data(raw_value)
192
+ sanitized[output_key] = sanitize_public_tool_output_data(raw_value, public_path_roots=public_path_roots)
161
193
  return sanitized
162
194
 
163
195
 
164
- def _sanitize_artifact_string(key: str, value: str) -> str | None:
196
+ def _sanitize_public_mapping_key(
197
+ key: Any,
198
+ *,
199
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
200
+ ) -> tuple[Any, bool]:
201
+ if not isinstance(key, str):
202
+ return key, False
203
+ sanitized_key = _sanitize_artifact_scalar_string(key, public_path_roots=public_path_roots)
204
+ return sanitized_key, sanitized_key != key and _is_path_like_mapping_key(key)
205
+
206
+
207
+ def _is_path_like_mapping_key(key: str) -> bool:
208
+ stripped = key.strip()
209
+ if not stripped or re.search(r"\s", stripped):
210
+ return False
211
+ if stripped.lower().startswith("file://"):
212
+ parsed = urlsplit(stripped)
213
+ return parsed.scheme.lower() == "file" and bool(parsed.path or parsed.netloc)
214
+ return bool(stripped.startswith("/") or stripped.startswith("\\\\") or ntpath.splitdrive(stripped)[0])
215
+
216
+
217
+ def _sanitize_artifact_string(
218
+ key: str,
219
+ value: str,
220
+ *,
221
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
222
+ ) -> str | None:
165
223
  if _is_artifact_uri_key(key):
166
224
  return value if is_valid_public_artifact_uri(value) else None
167
225
  if key.lower() in {"filename", "name"}:
@@ -171,34 +229,51 @@ def _sanitize_artifact_string(key: str, value: str) -> str | None:
171
229
  except UnsafeArtifactNameError:
172
230
  pass
173
231
  if value.lower().startswith("file://"):
174
- return "[PATH]"
175
- return _sanitize_artifact_scalar_string(value)
232
+ return relativize_public_file_uri(value, public_path_roots) or "[PATH]"
233
+ return _sanitize_artifact_scalar_string(value, public_path_roots=public_path_roots)
176
234
 
177
235
 
178
- def _sanitize_artifact_scalar_string(value: str) -> str:
236
+ def _sanitize_artifact_scalar_string(
237
+ value: str,
238
+ *,
239
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
240
+ ) -> str:
179
241
  if value.lower().startswith("file://"):
180
- return "[PATH]"
242
+ return relativize_public_file_uri(value, public_path_roots) or "[PATH]"
181
243
  decoded = unquote(value)
182
244
  if decoded != value:
183
245
  if decoded.lower().startswith("file://"):
184
- return "[PATH]"
185
- decoded_sanitized = sanitize_public_artifact_text(decoded, fallback_summary="")
246
+ return relativize_public_file_uri(decoded, public_path_roots) or "[PATH]"
247
+ decoded_sanitized = sanitize_public_artifact_text(
248
+ decoded,
249
+ fallback_summary="",
250
+ public_path_roots=public_path_roots,
251
+ )
186
252
  if decoded_sanitized != decoded:
187
253
  return decoded_sanitized
188
- return sanitize_public_artifact_text(value, fallback_summary="")
254
+ return sanitize_public_artifact_text(value, fallback_summary="", public_path_roots=public_path_roots)
189
255
 
190
256
 
191
- def sanitize_public_artifact_text(value: str, *, fallback_summary: str | None = None) -> str:
257
+ def sanitize_public_artifact_text(
258
+ value: str,
259
+ *,
260
+ fallback_summary: str | None = None,
261
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
262
+ ) -> str:
192
263
  if fallback_summary is None:
193
264
  fallback_summary = _("Unknown error")
194
265
  protected, placeholders = _replace_public_artifact_uri_tokens(value)
195
- protected = _replace_file_uri_tokens(protected)
196
- sanitized = sanitize_public_text(protected, fallback_summary=fallback_summary)
266
+ protected = _replace_file_uri_tokens(protected, public_path_roots=public_path_roots)
267
+ sanitized = sanitize_public_text(
268
+ protected,
269
+ fallback_summary=fallback_summary,
270
+ public_path_roots=public_path_roots,
271
+ )
197
272
  decoded_raw = unquote(protected)
198
273
  decoded, decoded_placeholders = _replace_public_artifact_uri_tokens(decoded_raw, prefix="__IAC_CODE_DECODED_URI_")
199
- decoded = _replace_file_uri_tokens(decoded)
274
+ decoded = _replace_file_uri_tokens(decoded, public_path_roots=public_path_roots)
200
275
  if decoded_raw != protected:
201
- decoded_sanitized = sanitize_public_text(decoded, fallback_summary="")
276
+ decoded_sanitized = sanitize_public_text(decoded, fallback_summary="", public_path_roots=public_path_roots)
202
277
  if decoded != decoded_raw or decoded_sanitized != decoded:
203
278
  sanitized = decoded_sanitized
204
279
  placeholders.update(decoded_placeholders)
@@ -207,13 +282,20 @@ def sanitize_public_artifact_text(value: str, *, fallback_summary: str | None =
207
282
  return sanitized
208
283
 
209
284
 
210
- def _replace_file_uri_tokens(value: str) -> str:
285
+ def _replace_file_uri_tokens(
286
+ value: str,
287
+ *,
288
+ public_path_roots: Iterable[Mapping[str, str]] | None = None,
289
+ ) -> str:
211
290
  def replace_file_uri(match: re.Match[str]) -> str:
212
291
  uri = match.group(0)
213
292
  trailing = ""
214
293
  while uri and uri[-1] in ".,:!?":
215
294
  trailing = uri[-1] + trailing
216
295
  uri = uri[:-1]
296
+ public_path = relativize_public_file_uri(uri, public_path_roots)
297
+ if public_path is not None:
298
+ return f"{public_path}{trailing}"
217
299
  return f"[PATH]{trailing}"
218
300
 
219
301
  return _FILE_URI_TEXT_PATTERN.sub(replace_file_uri, value)
@@ -333,8 +415,9 @@ class A2AArtifactMetadata:
333
415
 
334
416
 
335
417
  class A2AArtifactStore:
336
- def __init__(self, root: str | Path) -> None:
418
+ def __init__(self, root: str | Path, *, session_dir: str | Path | None = None) -> None:
337
419
  self.root = Path(root)
420
+ self._session_dir = Path(session_dir) if session_dir is not None else None
338
421
 
339
422
  def save_text(self, *, filename: str, content: str, media_type: str) -> A2AArtifactMetadata:
340
423
  encoded = content.encode("utf-8")
@@ -348,9 +431,12 @@ class A2AArtifactStore:
348
431
  safe_name = self._safe_filename(filename)
349
432
  artifact_id = str(uuid.uuid4())
350
433
  artifact_dir = self.root / artifact_id
351
- artifact_dir.mkdir(parents=True, exist_ok=False)
434
+ if self._session_dir is not None:
435
+ ensure_session_owned_dir(self._session_dir, artifact_dir)
436
+ else:
437
+ artifact_dir.mkdir(parents=True, exist_ok=False)
352
438
  path = artifact_dir / safe_name
353
- path.write_bytes(content)
439
+ atomic_write_bytes(path, content)
354
440
  return A2AArtifactMetadata(
355
441
  artifact_id=artifact_id,
356
442
  filename=safe_name,
@@ -373,3 +459,13 @@ class A2AArtifactStore:
373
459
  @staticmethod
374
460
  def _safe_filename(filename: str) -> str:
375
461
  return safe_artifact_filename(filename)
462
+
463
+
464
+ def artifact_store_for_session(session_dir: str | Path) -> A2AArtifactStore:
465
+ session_path = Path(session_dir)
466
+ version = require_supported_session_layout(session_path)
467
+ if version != SESSION_LAYOUT_VERSION_V2:
468
+ raise UnsupportedSessionLayoutError(_("Unsupported session layout version: {version}").format(version="legacy"))
469
+ session_paths = SessionPaths.from_session_dir(session_path)
470
+ root = ensure_session_owned_dir(session_path, session_paths.a2a_artifacts_dir)
471
+ return A2AArtifactStore(root, session_dir=session_path)
@@ -0,0 +1,91 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from typing import Any
6
+
7
+ from iac_code.i18n import _
8
+ from iac_code.services.session_backup import BackupReason, SessionBackupBlocked
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ async def backup_session_async(
14
+ backup_service: Any,
15
+ cwd: str,
16
+ session_id: str,
17
+ *,
18
+ reason: BackupReason,
19
+ critical: bool,
20
+ metrics: Any | None = None,
21
+ ) -> Any | None:
22
+ failed_recorded = False
23
+ try:
24
+ result = await asyncio.to_thread(
25
+ backup_service.backup_session,
26
+ cwd,
27
+ session_id,
28
+ reason=reason,
29
+ critical=critical,
30
+ )
31
+ retry_count = _retry_count(result)
32
+ if getattr(result, "enabled", False) and not getattr(result, "succeeded", True):
33
+ message = str(
34
+ getattr(result, "error", None) or _("Session backup failed. Retry after the backup path is available.")
35
+ )
36
+ _record_backup_failed(metrics, reason=reason, critical=critical, retry_count=retry_count)
37
+ failed_recorded = True
38
+ if critical:
39
+ raise SessionBackupBlocked(message, retry_count=retry_count, result=result)
40
+ logger.warning(
41
+ "A2A session backup failed reason=%s critical=%s retry_count=%s: %s",
42
+ reason.value,
43
+ critical,
44
+ retry_count,
45
+ message,
46
+ )
47
+ elif getattr(result, "enabled", False):
48
+ _record_backup_succeeded(metrics, reason=reason, critical=critical, retry_count=retry_count)
49
+ return result
50
+ except Exception as exc:
51
+ retry_count = _retry_count_from_exception(exc)
52
+ if not failed_recorded:
53
+ _record_backup_failed(metrics, reason=reason, critical=critical, retry_count=retry_count)
54
+ if critical:
55
+ raise
56
+ logger.warning(
57
+ "A2A session backup failed reason=%s critical=%s retry_count=%s error_type=%s",
58
+ reason.value,
59
+ critical,
60
+ retry_count,
61
+ type(exc).__name__,
62
+ )
63
+ return None
64
+
65
+
66
+ def _retry_count(result: Any) -> int:
67
+ value = getattr(result, "retry_count", 0)
68
+ return value if isinstance(value, int) and value >= 0 else 0
69
+
70
+
71
+ def _retry_count_from_exception(exc: BaseException) -> int:
72
+ value = getattr(exc, "retry_count", 0)
73
+ return value if isinstance(value, int) and value >= 0 else 0
74
+
75
+
76
+ def _record_backup_succeeded(metrics: Any | None, *, reason: BackupReason, critical: bool, retry_count: int) -> None:
77
+ record = getattr(metrics, "record_backup_succeeded", None)
78
+ if callable(record):
79
+ try:
80
+ record(reason=reason.value, critical=critical, retry_count=retry_count)
81
+ except Exception as exc:
82
+ logger.debug("Failed to record A2A backup_succeeded metric: %s", type(exc).__name__)
83
+
84
+
85
+ def _record_backup_failed(metrics: Any | None, *, reason: BackupReason, critical: bool, retry_count: int) -> None:
86
+ record = getattr(metrics, "record_backup_failed", None)
87
+ if callable(record):
88
+ try:
89
+ record(reason=reason.value, critical=critical, retry_count=retry_count)
90
+ except Exception as exc:
91
+ logger.debug("Failed to record A2A backup_failed metric: %s", type(exc).__name__)
@@ -176,10 +176,15 @@ def _extract_artifact_metadata(result: Any, artifact_store: Any | None) -> dict[
176
176
  return None
177
177
 
178
178
 
179
- def _tool_result_metadata(result: Any, *, is_error: bool = False) -> Any:
180
- sanitized = sanitize_public_tool_output_data(result)
179
+ def _tool_result_metadata(
180
+ result: Any,
181
+ *,
182
+ is_error: bool = False,
183
+ public_path_roots: list[dict[str, str]] | None = None,
184
+ ) -> Any:
185
+ sanitized = sanitize_public_tool_output_data(result, public_path_roots=public_path_roots)
181
186
  if is_error and isinstance(sanitized, str):
182
- return sanitize_public_artifact_text(sanitized)
187
+ return sanitize_public_artifact_text(sanitized, public_path_roots=public_path_roots)
183
188
  return _truncate(sanitized)
184
189
 
185
190
 
@@ -351,7 +356,11 @@ async def publish_stream_event(
351
356
  "status": "failed" if event.is_error else "completed",
352
357
  "toolUseId": event.tool_use_id,
353
358
  "name": event.tool_name,
354
- "result": _tool_result_metadata(event.result, is_error=event.is_error),
359
+ "result": _tool_result_metadata(
360
+ event.result,
361
+ is_error=event.is_error,
362
+ public_path_roots=event.public_path_roots,
363
+ ),
355
364
  }
356
365
  if artifact_metadata is not None:
357
366
  tool_metadata["artifact"] = artifact_metadata
@@ -455,7 +464,7 @@ async def publish_stream_event(
455
464
  if event.error_id:
456
465
  error_metadata["errorId"] = event.error_id
457
466
  if event.is_retryable:
458
- text = "A temporary error occurred. Please retry."
467
+ text = _("A temporary error occurred. Please retry.")
459
468
  state = TaskState.TASK_STATE_INPUT_REQUIRED
460
469
  else:
461
470
  raw = event.error or "Unknown error"