iris-devtester 1.9.2__tar.gz → 1.10.0__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 (241) hide show
  1. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/AGENTS.md +129 -0
  2. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/PKG-INFO +84 -1
  3. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/README.md +83 -0
  4. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/SKILL.md +1 -1
  5. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/__init__.py +1 -1
  6. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/cli/container.py +228 -13
  7. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/container_config.py +16 -11
  8. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/container_state.py +6 -7
  9. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/yaml_loader.py +1 -1
  10. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/iris_container.py +92 -13
  11. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/ports/registry.py +2 -2
  12. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester.egg-info/PKG-INFO +84 -1
  13. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/pyproject.toml +1 -1
  14. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/config/test_container_config.py +13 -2
  15. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_iris_container.py +47 -3
  16. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/utils/test_iris_container_adapter.py +1 -1
  17. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/CLAUDE.md +0 -0
  18. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/CONSTITUTION.md +0 -0
  19. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/LICENSE +0 -0
  20. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/MANIFEST.in +0 -0
  21. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/GETTING_STARTED.md +0 -0
  22. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/LANGCHAIN_INTEGRATION_QUICKSTART.md +0 -0
  23. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/ROADMAP.md +0 -0
  24. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/SQL_VS_OBJECTSCRIPT.md +0 -0
  25. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/TROUBLESHOOTING.md +0 -0
  26. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/WHATS_NEW_v1.4.0.md +0 -0
  27. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/AGENTIC_SANDBOX_ENHANCEMENT_REPORT.md +0 -0
  28. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/IMPACT_ANALYSIS.md +0 -0
  29. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/IRIS_DEVTESTER_POSITIONING_REPORT.md +0 -0
  30. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/LANGCHAIN_INTEGRATION_STRATEGY.md +0 -0
  31. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/LANGCHAIN_INTEGRATION_TEST_RESULTS.md +0 -0
  32. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/PHASE_2_PLAN.md +0 -0
  33. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/RAG_TEMPLATES_ANALYSIS.md +0 -0
  34. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/README.md +0 -0
  35. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/STRATEGIC_ROADMAP_SUMMARY.md +0 -0
  36. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/archive/feature-009-refactor-plan.md +0 -0
  37. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/BUG_REPORT.md +0 -0
  38. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/EXTRACTION_SUMMARY.md +0 -0
  39. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/FEATURE_006_SUMMARY.md +0 -0
  40. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/PHASE2_RESULTS.md +0 -0
  41. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/PRE_PUBLISH_REVIEW.md +0 -0
  42. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/PROGRESS.md +0 -0
  43. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/PYPI_READINESS.md +0 -0
  44. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/SESSION-INTEGRATION-TESTS.md +0 -0
  45. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/SESSION-SUMMARY.md +0 -0
  46. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/STATUS-002-PIVOTED.md +0 -0
  47. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/STATUS-003-COMPLETE.md +0 -0
  48. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/STATUS.md +0 -0
  49. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/V1_COMPLETION_PLAN.md +0 -0
  50. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/development/V1_RELEASE_SUMMARY.md +0 -0
  51. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/features/WSGI-ASGI-SERVER-SETUP.md +0 -0
  52. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/features/agent-skills.md +0 -0
  53. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/features/dat-fixtures.md +0 -0
  54. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/features/docker-compose.md +0 -0
  55. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/features/performance-monitoring.md +0 -0
  56. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/features/testcontainers.md +0 -0
  57. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/api-contract-synchronization.md +0 -0
  58. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/callin-service-requirement.md +0 -0
  59. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/cpf-merge-and-container-restarts.md +0 -0
  60. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/dat-fixtures-docker-exec-pattern.md +0 -0
  61. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/dat-restore-database-isolation-problem.md +0 -0
  62. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/dbapi-bulk-insert-performance-issue.md +0 -0
  63. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/dbapi-objectscript-limitation.md +0 -0
  64. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/dbapi-password-reset-limitation.md +0 -0
  65. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/dbapi-private-module-myth.md +0 -0
  66. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/docker-hub-image-naming.md +0 -0
  67. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/embedded-python-considerations.md +0 -0
  68. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/feature-002-pivot-summary.md +0 -0
  69. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/integration-test-dbapi-limitation.md +0 -0
  70. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/iris-backup-patterns.md +0 -0
  71. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/iris-container-performance.md +0 -0
  72. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/iris-container-readiness.md +0 -0
  73. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/iris-docker-sdk-environment-variables.md +0 -0
  74. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/iris-performance-monitoring-landscape.md +0 -0
  75. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/iris-security-users-api.md +0 -0
  76. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/password-reset-changeflag-fix.md +0 -0
  77. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/rag-templates-production-patterns.md +0 -0
  78. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/sql-task-manager-operations.md +0 -0
  79. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/test-isolation-fix-summary.md +0 -0
  80. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/test-isolation-investigation.md +0 -0
  81. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/docs/learnings/testcontainers-ryuk-lifecycle.md +0 -0
  82. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/01_quickstart.py +0 -0
  83. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/02_connection_management.py +0 -0
  84. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/04_pytest_fixtures.py +0 -0
  85. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/05_ci_cd.py +0 -0
  86. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/08_auto_discovery.py +0 -0
  87. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/09_enterprise.py +0 -0
  88. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/10_docker_compose_integration.py +0 -0
  89. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/examples/langchain_integration_example.py +0 -0
  90. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/cli/__init__.py +0 -0
  91. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/cli/__main__.py +0 -0
  92. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/cli/connection_commands.py +0 -0
  93. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/cli/container_commands.py +0 -0
  94. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/cli/fixture_commands.py +0 -0
  95. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/__init__.py +0 -0
  96. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/auto_discovery.py +0 -0
  97. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/defaults.py +0 -0
  98. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/discovery.py +0 -0
  99. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/models.py +0 -0
  100. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/config/presets.py +0 -0
  101. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/__init__.py +1 -1
  102. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/auto_discovery.py +0 -0
  103. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/connection.py +0 -0
  104. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/dbapi.py +0 -0
  105. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/jdbc.py +0 -0
  106. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/manager.py +0 -0
  107. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/models.py +0 -0
  108. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/connections/retry.py +0 -0
  109. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/__init__.py +0 -0
  110. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/cpf_manager.py +0 -0
  111. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/models.py +0 -0
  112. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/monitor_utils.py +0 -0
  113. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/monitoring.py +0 -0
  114. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/performance.py +0 -0
  115. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/validation.py +0 -0
  116. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/containers/wait_strategies.py +0 -0
  117. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/fixtures/__init__.py +0 -0
  118. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/fixtures/creator.py +0 -0
  119. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/fixtures/loader.py +0 -0
  120. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/fixtures/manifest.py +0 -0
  121. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/fixtures/obj_export.py +0 -0
  122. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/fixtures/validator.py +0 -0
  123. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/integrations/__init__.py +0 -0
  124. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/integrations/langchain.py +0 -0
  125. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/ports/__init__.py +0 -0
  126. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/ports/assignment.py +0 -0
  127. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/ports/exceptions.py +0 -0
  128. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/testing/__init__.py +0 -0
  129. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/testing/fixtures.py +0 -0
  130. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/testing/helpers.py +0 -0
  131. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/testing/models.py +0 -0
  132. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/testing/schema_reset.py +0 -0
  133. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/__init__.py +0 -0
  134. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/container_port.py +0 -0
  135. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/container_status.py +0 -0
  136. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/dbapi_compat.py +0 -0
  137. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/enable_callin.py +0 -0
  138. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/health_checks.py +0 -0
  139. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/iris_container_adapter.py +0 -0
  140. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/password.py +0 -0
  141. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/progress.py +0 -0
  142. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester/utils/test_connection.py +0 -0
  143. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester.egg-info/SOURCES.txt +0 -0
  144. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester.egg-info/dependency_links.txt +0 -0
  145. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester.egg-info/entry_points.txt +0 -0
  146. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester.egg-info/requires.txt +0 -0
  147. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/iris_devtester.egg-info/top_level.txt +0 -0
  148. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/setup.cfg +0 -0
  149. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/__init__.py +0 -0
  150. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/conftest.py +0 -0
  151. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/__init__.py +0 -0
  152. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_logs_contract.py +0 -0
  153. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_remove_contract.py +0 -0
  154. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_restart_contract.py +0 -0
  155. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_start_contract.py +0 -0
  156. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_status_contract.py +0 -0
  157. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_stop_contract.py +0 -0
  158. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/cli/test_container_up_contract.py +0 -0
  159. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_agent_skills.py +0 -0
  160. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_cli_container_commands.py +0 -0
  161. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_cli_fixture_commands.py +0 -0
  162. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_connection_api.py +0 -0
  163. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_container_api.py +0 -0
  164. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_container_integration_contract.py +0 -0
  165. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_container_status_api.py +0 -0
  166. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_container_validation_api.py +0 -0
  167. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_enable_callin_api.py +0 -0
  168. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_fixture_creator_api.py +0 -0
  169. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_fixture_loader_api.py +0 -0
  170. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_fixture_validator_api.py +0 -0
  171. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_iriscontainer_attach.py +0 -0
  172. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_legacy_package_contract.py +0 -0
  173. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_modern_package_contract.py +0 -0
  174. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_monitoring_config_api.py +0 -0
  175. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_package_detection.py +0 -0
  176. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_port_registry_contract.py +0 -0
  177. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_preconfig_contract.py +0 -0
  178. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_reset_verification_contract.py +0 -0
  179. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_resource_monitoring_api.py +0 -0
  180. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_retry_logic_contract.py +0 -0
  181. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_task_manager_api.py +0 -0
  182. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_test_connection_api.py +0 -0
  183. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/contract/test_testing_fixtures_api.py +0 -0
  184. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/e2e/__init__.py +0 -0
  185. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/e2e/test_skill_workflow.py +0 -0
  186. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/__init__.py +0 -0
  187. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/conftest.py +0 -0
  188. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/ports/__init__.py +0 -0
  189. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/ports/test_manual_port_override.py +0 -0
  190. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/ports/test_multi_project_isolation.py +0 -0
  191. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/ports/test_port_exhaustion.py +0 -0
  192. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/ports/test_port_persistence.py +0 -0
  193. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/ports/test_stale_cleanup.py +0 -0
  194. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_bug_fixes.py +0 -0
  195. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_bug_fixes_011.py +0 -0
  196. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_cli_container_integration.py +0 -0
  197. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_connection_integration.py +0 -0
  198. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_container_health_monitor.py +0 -0
  199. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_container_status_integration.py +0 -0
  200. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_container_validation.py +0 -0
  201. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_cpf_merge.py +0 -0
  202. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_cpf_presets.py +0 -0
  203. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_cpf_security.py +0 -0
  204. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_custom_user_remediation.py +0 -0
  205. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_dat_fixtures_integration.py +0 -0
  206. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_enable_callin_integration.py +0 -0
  207. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_fixture_export_patterns.py +0 -0
  208. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_fixture_performance.py +0 -0
  209. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_fixture_refresh.py +0 -0
  210. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_iriscontainer_attach_integration.py +0 -0
  211. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_monitor_utils_integration.py +0 -0
  212. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_monitoring_integration.py +0 -0
  213. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_password_preconfig_integration.py +0 -0
  214. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_password_reset_both_editions.py +0 -0
  215. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_password_reset_integration.py +0 -0
  216. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_password_reset_macos.py +0 -0
  217. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_password_reset_timing.py +0 -0
  218. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_password_reset_validation.py +0 -0
  219. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_proactive_password_reset.py +0 -0
  220. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_real_world_problems.py +0 -0
  221. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_reliable_password_reset.py +0 -0
  222. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/integration/test_test_connection_integration.py +0 -0
  223. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/__init__.py +0 -0
  224. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/config/test_config_hierarchy.py +0 -0
  225. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/config/test_yaml_loader.py +0 -0
  226. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_auto_discovery.py +0 -0
  227. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_config_discovery.py +0 -0
  228. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_connection_fallback.py +0 -0
  229. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_connection_info.py +0 -0
  230. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_cpf_manager.py +0 -0
  231. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_iris_config.py +0 -0
  232. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_manifest.py +0 -0
  233. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_monitoring_policy.py +0 -0
  234. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_password_preconfig.py +0 -0
  235. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_password_preconfig_unit.py +0 -0
  236. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_performance_metrics.py +0 -0
  237. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_resource_thresholds.py +0 -0
  238. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_retry.py +0 -0
  239. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_schema_models.py +0 -0
  240. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_validation_results.py +0 -0
  241. {iris_devtester-1.9.2 → iris_devtester-1.10.0}/tests/unit/test_wait_strategies.py +0 -0
@@ -287,3 +287,132 @@ The repository exposes core functionality as "Skills" to help AI agents work aut
287
287
 
288
288
  ## Recent Changes
289
289
  - 023-docs-cleanup: Added N/A (documentation only)
290
+ ---
291
+
292
+ ## COMPOUND KNOWLEDGE BASE & DEVELOPMENT ENVIRONMENT
293
+
294
+ **Last Updated**: $(date +%Y-%m-%d)
295
+
296
+ > Central registry of development knowledge, tools, capabilities, and automation
297
+
298
+
299
+ ### 📚 Knowledge Base
300
+
301
+ **Location**: `~/.config/opencode/compound-knowledge/`
302
+
303
+
304
+ **Structure**:
305
+ - `global/` - Project-agnostic knowledge (frameworks, tools, patterns)
306
+ - `projects/[name]/` - Project-specific knowledge (domain, architecture)
307
+
308
+ **Stats**: 7 solutions (7 global, 0 project)
309
+
310
+ **Quick Search**:
311
+ ```bash
312
+ # Search everything
313
+ grep -ri "keywords" ~/.config/opencode/compound-knowledge/
314
+
315
+ # Global only
316
+ grep -ri "keywords" ~/.config/opencode/compound-knowledge/global/
317
+
318
+ # This project
319
+ grep -ri "keywords" ~/.config/opencode/compound-knowledge/projects/$(basename $(pwd))/
320
+ ```
321
+
322
+ **Time Savings**: First solve: 30min → Next solve: 3min (90% faster)
323
+
324
+
325
+ ### 🔌 MCP Servers
326
+
327
+ - `atlassian` - local
328
+ - `gemini-impl` - local
329
+ - `hallucination-detector` - local
330
+ - `jama` - local
331
+ - `perplexity` - local
332
+ - `playwright` - local
333
+ - `qwen-impl` - local
334
+ - `support-tools` - local
335
+
336
+ ### 🤖 Automation & Hooks
337
+
338
+ **Orchestrator Behavior** (configured via `~/.config/opencode/oh-my-opencode-slim.json`):
339
+ - **Before tasks**: Search compound KB for similar solutions
340
+ - **After completion**: Remind to document solution
341
+
342
+ **Periodic Maintenance** (recommended):
343
+ ```bash
344
+ # Weekly: Regenerate KB index
345
+ ~/.config/opencode/compound-knowledge/generate-index.sh
346
+
347
+ # Monthly: Review and consolidate similar solutions
348
+ # Quarterly: Extract patterns from repeated solutions
349
+ ```
350
+
351
+ **Auto-Documentation Triggers**:
352
+ - Tests pass after fixing failure → Document solution
353
+ - Error resolved → Document fix
354
+ - Performance improved → Document optimization
355
+ - Integration working → Document configuration
356
+
357
+
358
+ ### 🛠️ Tools & Utilities
359
+
360
+ **Compound Engineering**:
361
+ - `~/.config/opencode/compound-knowledge/new-solution.sh` - Create solution doc
362
+ - `~/.config/opencode/compound-knowledge/generate-index.sh` - Regenerate index
363
+ - `~/.config/opencode/compound-knowledge/sync-to-agents.sh` - Update AGENTS.md files
364
+
365
+ **OpenCode Agents** (oh-my-opencode-slim):
366
+ - `orchestrator` - Master coordinator (with compound engineering)
367
+ - `explorer` - Codebase reconnaissance
368
+ - `oracle` - Strategic advisor
369
+ - `librarian` - External knowledge (websearch, context7, grep_app MCPs)
370
+ - `designer` - UI/UX implementation
371
+ - `fixer` - Fast implementation
372
+ - `code-simplifier` - Post-work code refinement
373
+
374
+
375
+ ### 🎯 Skills
376
+
377
+ **speckit** (feature specification):
378
+ - `speckit.plan` - Implementation planning
379
+ - `speckit.specify` - Feature specification
380
+ - `speckit.tasks` - Task generation
381
+ - `speckit.implement` - Implementation guidance
382
+
383
+
384
+ ### 📋 Quick Reference
385
+
386
+ **Full Index**: `~/.config/opencode/compound-knowledge/INDEX.md`
387
+
388
+ **Documentation Templates**:
389
+ ```markdown
390
+ ---
391
+ title: "Problem description"
392
+ category: [build-errors|test-failures|runtime-errors|performance-issues|
393
+ database-issues|security-issues|ui-bugs|integration-issues|logic-errors]
394
+ date: YYYY-MM-DD
395
+ severity: high|medium|low
396
+ tags: [tag1, tag2]
397
+ time_to_solve: XXmin
398
+ ---
399
+
400
+ ## Problem Symptom
401
+ [What was observed]
402
+
403
+ ## Solution
404
+ [How you fixed it]
405
+
406
+ ## Prevention
407
+ [How to avoid future]
408
+ ```
409
+
410
+ **Decision Tree** (Global vs Project-Specific):
411
+ - Framework/tool issue → `global/`
412
+ - General pattern → `global/`
413
+ - Project domain logic → `projects/[name]/`
414
+ - Project architecture → `projects/[name]/`
415
+ - When in doubt → `global/`
416
+
417
+ ---
418
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris-devtester
3
- Version: 1.9.2
3
+ Version: 1.10.0
4
4
  Summary: Battle-tested InterSystems IRIS infrastructure utilities for Python development
5
5
  Author-email: InterSystems Community <community@intersystems.com>
6
6
  Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
@@ -107,6 +107,89 @@ def test_connection():
107
107
  assert cursor.fetchone()[0] == 1
108
108
  ```
109
109
 
110
+ ## Container Editions
111
+
112
+ Three canonical container editions are available:
113
+
114
+ | Edition | Size | Use Case | Image |
115
+ |---------|------|----------|-------|
116
+ | **Community** | ~972MB | Development, testing | `intersystemsdc/iris-community` |
117
+ | **Enterprise** | ~1GB+ | Production testing | `containers.intersystems.com/intersystems/iris` |
118
+ | **Light** | **~580MB** | CI/CD pipelines | `caretdev/iris-community-light` |
119
+
120
+ ### Python API
121
+ ```python
122
+ from iris_devtester.containers import IRISContainer
123
+
124
+ # Community Edition (auto-detects ARM64 vs x86)
125
+ with IRISContainer.community() as iris:
126
+ conn = iris.get_connection()
127
+
128
+ # Light Edition (85% smaller, for CI/CD)
129
+ with IRISContainer.light() as iris:
130
+ conn = iris.get_connection()
131
+
132
+ # Enterprise Edition (requires license)
133
+ with IRISContainer.enterprise(license_key="/path/to/iris.key") as iris:
134
+ conn = iris.get_connection()
135
+
136
+ # Specify version
137
+ with IRISContainer.community(version="2025.1") as iris:
138
+ conn = iris.get_connection()
139
+ ```
140
+
141
+ ### CLI Usage
142
+ ```bash
143
+ # Community (default)
144
+ iris-devtester container up
145
+
146
+ # Light edition for CI/CD
147
+ iris-devtester container up --edition light
148
+
149
+ # Enterprise edition with license
150
+ iris-devtester container up --edition enterprise --license /path/to/iris.key
151
+
152
+ # List running IRIS containers
153
+ iris-devtester container list
154
+ ```
155
+
156
+ ### Light Edition Details
157
+
158
+ The Light edition removes components unnecessary for SQL-only workloads:
159
+ - **Removed**: Interoperability/Ensemble, Management Portal, DeepSee/BI, CSP/REST
160
+ - **Kept**: SQL engine, DBAPI, JDBC, ODBC, SQLAlchemy-IRIS support
161
+
162
+ Perfect for microservices, automated testing, and Python/SQL pipelines.
163
+
164
+ ### Builder Methods
165
+ ```python
166
+ # Set a custom container name (for debugging, logs, multiple containers)
167
+ iris = IRISContainer.community().with_name("my-test-db")
168
+
169
+ # Set credentials
170
+ iris = IRISContainer.community().with_credentials("_SYSTEM", "MyPassword")
171
+
172
+ # Pre-configure password (set via IRIS_PASSWORD env var at startup)
173
+ iris = IRISContainer.community().with_preconfigured_password("MyPassword")
174
+
175
+ # Chain multiple options
176
+ with IRISContainer.community() \
177
+ .with_name("integration-test-db") \
178
+ .with_credentials("_SYSTEM", "TestPass123") as iris:
179
+ conn = iris.get_connection()
180
+ ```
181
+
182
+ ### Constructor Parameters
183
+ ```python
184
+ IRISContainer(
185
+ image="intersystemsdc/iris-community:latest", # Docker image
186
+ username="SuperUser", # Default username
187
+ password="SYS", # Default password
188
+ namespace="USER", # Default namespace
189
+ name="my-container", # Container name (alternative to with_name)
190
+ )
191
+ ```
192
+
110
193
  ## Key Features
111
194
 
112
195
  - **🔐 Automatic Password Management**: Remediates security flags using official system APIs.
@@ -43,6 +43,89 @@ def test_connection():
43
43
  assert cursor.fetchone()[0] == 1
44
44
  ```
45
45
 
46
+ ## Container Editions
47
+
48
+ Three canonical container editions are available:
49
+
50
+ | Edition | Size | Use Case | Image |
51
+ |---------|------|----------|-------|
52
+ | **Community** | ~972MB | Development, testing | `intersystemsdc/iris-community` |
53
+ | **Enterprise** | ~1GB+ | Production testing | `containers.intersystems.com/intersystems/iris` |
54
+ | **Light** | **~580MB** | CI/CD pipelines | `caretdev/iris-community-light` |
55
+
56
+ ### Python API
57
+ ```python
58
+ from iris_devtester.containers import IRISContainer
59
+
60
+ # Community Edition (auto-detects ARM64 vs x86)
61
+ with IRISContainer.community() as iris:
62
+ conn = iris.get_connection()
63
+
64
+ # Light Edition (85% smaller, for CI/CD)
65
+ with IRISContainer.light() as iris:
66
+ conn = iris.get_connection()
67
+
68
+ # Enterprise Edition (requires license)
69
+ with IRISContainer.enterprise(license_key="/path/to/iris.key") as iris:
70
+ conn = iris.get_connection()
71
+
72
+ # Specify version
73
+ with IRISContainer.community(version="2025.1") as iris:
74
+ conn = iris.get_connection()
75
+ ```
76
+
77
+ ### CLI Usage
78
+ ```bash
79
+ # Community (default)
80
+ iris-devtester container up
81
+
82
+ # Light edition for CI/CD
83
+ iris-devtester container up --edition light
84
+
85
+ # Enterprise edition with license
86
+ iris-devtester container up --edition enterprise --license /path/to/iris.key
87
+
88
+ # List running IRIS containers
89
+ iris-devtester container list
90
+ ```
91
+
92
+ ### Light Edition Details
93
+
94
+ The Light edition removes components unnecessary for SQL-only workloads:
95
+ - **Removed**: Interoperability/Ensemble, Management Portal, DeepSee/BI, CSP/REST
96
+ - **Kept**: SQL engine, DBAPI, JDBC, ODBC, SQLAlchemy-IRIS support
97
+
98
+ Perfect for microservices, automated testing, and Python/SQL pipelines.
99
+
100
+ ### Builder Methods
101
+ ```python
102
+ # Set a custom container name (for debugging, logs, multiple containers)
103
+ iris = IRISContainer.community().with_name("my-test-db")
104
+
105
+ # Set credentials
106
+ iris = IRISContainer.community().with_credentials("_SYSTEM", "MyPassword")
107
+
108
+ # Pre-configure password (set via IRIS_PASSWORD env var at startup)
109
+ iris = IRISContainer.community().with_preconfigured_password("MyPassword")
110
+
111
+ # Chain multiple options
112
+ with IRISContainer.community() \
113
+ .with_name("integration-test-db") \
114
+ .with_credentials("_SYSTEM", "TestPass123") as iris:
115
+ conn = iris.get_connection()
116
+ ```
117
+
118
+ ### Constructor Parameters
119
+ ```python
120
+ IRISContainer(
121
+ image="intersystemsdc/iris-community:latest", # Docker image
122
+ username="SuperUser", # Default username
123
+ password="SYS", # Default password
124
+ namespace="USER", # Default namespace
125
+ name="my-container", # Container name (alternative to with_name)
126
+ )
127
+ ```
128
+
46
129
  ## Key Features
47
130
 
48
131
  - **🔐 Automatic Password Management**: Remediates security flags using official system APIs.
@@ -3,7 +3,7 @@ name: iris-devtester
3
3
  description: Battle-tested InterSystems IRIS infrastructure utilities for Python database testing.
4
4
  triggers: [iris, database, testing, container, fixture, gof, connection, remediation]
5
5
  metadata:
6
- version: 1.9.2
6
+ version: 1.10.0
7
7
  author: InterSystems Community
8
8
  principles: [library-first, dbapi-first, isolation-by-default, fail-fast]
9
9
  ---
@@ -26,7 +26,7 @@ LangChain Integration:
26
26
  ... # Build your RAG app...
27
27
  """
28
28
 
29
- __version__ = "1.9.2"
29
+ __version__ = "1.10.0"
30
30
  __author__ = "InterSystems Community"
31
31
  __license__ = "MIT"
32
32
 
@@ -31,6 +31,25 @@ def container_group(ctx):
31
31
  @click.option(
32
32
  "--config", type=click.Path(exists=True), help="Path to iris-config.yml configuration file"
33
33
  )
34
+ @click.option(
35
+ "--name",
36
+ type=str,
37
+ default=None,
38
+ help="Container name (default: iris_db)",
39
+ )
40
+ @click.option(
41
+ "--edition",
42
+ type=click.Choice(["community", "enterprise", "light"], case_sensitive=False),
43
+ default="community",
44
+ help="IRIS edition: community (default), enterprise (requires license), light (minimal for CI/CD)",
45
+ )
46
+ @click.option(
47
+ "--license",
48
+ "license_key",
49
+ type=click.Path(exists=True),
50
+ default=None,
51
+ help="Path to iris.key license file (required for enterprise edition)",
52
+ )
34
53
  @click.option(
35
54
  "--detach/--no-detach",
36
55
  default=True,
@@ -41,7 +60,7 @@ def container_group(ctx):
41
60
  )
42
61
  @click.option("--cpf", help="Path to CPF merge file or raw CPF content")
43
62
  @click.pass_context
44
- def up(ctx, config, detach, timeout, cpf):
63
+ def up(ctx, config, name, edition, license_key, detach, timeout, cpf):
45
64
  """
46
65
  Create and start IRIS container from configuration.
47
66
 
@@ -58,15 +77,18 @@ def up(ctx, config, detach, timeout, cpf):
58
77
  # Zero-config (uses Community edition defaults)
59
78
  iris-devtester container up
60
79
 
80
+ # Light edition for CI/CD (85% smaller, faster startup)
81
+ iris-devtester container up --edition light
82
+
83
+ # Enterprise edition with license
84
+ iris-devtester container up --edition enterprise --license /path/to/iris.key
85
+
86
+ # With custom container name
87
+ iris-devtester container up --name my-test-db
88
+
61
89
  # With custom configuration including volumes
62
90
  iris-devtester container up --config iris-config.yml
63
91
 
64
- # Example iris-config.yml with volumes:
65
- # edition: community
66
- # volumes:
67
- # - ./workspace:/external/workspace
68
- # - ./config:/opt/config:ro
69
-
70
92
  # Foreground mode (see logs)
71
93
  iris-devtester container up --no-detach
72
94
  """
@@ -85,6 +107,37 @@ def up(ctx, config, detach, timeout, cpf):
85
107
  container_config = ContainerConfig.default()
86
108
  click.echo("⚡ Creating container from zero-config defaults")
87
109
 
110
+ # Override container name if provided via --name
111
+ if name:
112
+ container_config.container_name = name
113
+ click.echo(f" → Container name: {name}")
114
+
115
+ # Override edition if provided via --edition
116
+ if edition:
117
+ edition_lower = edition.lower()
118
+ container_config.edition = edition_lower
119
+
120
+ # Set appropriate image based on edition
121
+ if edition_lower == "light":
122
+ # Light edition: caretdev/iris-community-light (85% smaller)
123
+ container_config.image_tag = "latest-em"
124
+ click.echo(
125
+ click.style(f" → Edition: light", fg="cyan")
126
+ + " (minimal for CI/CD, ~580MB vs ~3.5GB)"
127
+ )
128
+ elif edition_lower == "enterprise":
129
+ if not license_key:
130
+ raise click.ClickException(
131
+ "Enterprise edition requires --license option.\n"
132
+ "\n"
133
+ "Usage: iris-devtester container up --edition enterprise --license /path/to/iris.key"
134
+ )
135
+ container_config.license_key = license_key
136
+ click.echo(f" → Edition: enterprise")
137
+ click.echo(f" → License: {license_key}")
138
+ else:
139
+ click.echo(f" → Edition: community")
140
+
88
141
  if cpf:
89
142
  container_config.cpf_merge = cpf
90
143
  click.echo(f" → CPF Merge: {cpf[:50]}...")
@@ -95,6 +148,36 @@ def up(ctx, config, detach, timeout, cpf):
95
148
  if existing_container:
96
149
  # Container exists - check if running
97
150
  existing_container.reload()
151
+
152
+ # Warn if using default name and container already exists
153
+ # (user might be connecting to wrong container from different project)
154
+ if container_config.container_name == "iris_db" and not name:
155
+ existing_image = (
156
+ existing_container.image.tags[0] if existing_container.image.tags else "unknown"
157
+ )
158
+ click.echo("")
159
+ click.echo(
160
+ click.style(
161
+ "⚠️ WARNING: Using default container name 'iris_db'", fg="yellow", bold=True
162
+ )
163
+ )
164
+ click.echo(
165
+ click.style(
166
+ f" A container with this name already exists (image: {existing_image})",
167
+ fg="yellow",
168
+ )
169
+ )
170
+ click.echo(
171
+ click.style(
172
+ " If this is from a different project, use --name to avoid conflicts:",
173
+ fg="yellow",
174
+ )
175
+ )
176
+ click.echo(
177
+ click.style(" iris-devtester container up --name my-project-db", fg="cyan")
178
+ )
179
+ click.echo("")
180
+
98
181
  if existing_container.status == "running":
99
182
  click.echo(f"✓ Container '{container_config.container_name}' is already running")
100
183
 
@@ -228,6 +311,141 @@ def up(ctx, config, detach, timeout, cpf):
228
311
  ctx.exit(1)
229
312
 
230
313
 
314
+ @container_group.command(name="list")
315
+ @click.option(
316
+ "--all", "-a", "show_all", is_flag=True, help="Show all containers (including stopped)"
317
+ )
318
+ @click.option(
319
+ "--format",
320
+ "output_format",
321
+ type=click.Choice(["table", "json"], case_sensitive=False),
322
+ default="table",
323
+ help="Output format (default: table)",
324
+ )
325
+ @click.pass_context
326
+ def list_containers(ctx, show_all, output_format):
327
+ """
328
+ List IRIS containers.
329
+
330
+ Shows all IRIS containers managed by iris-devtester, with their status,
331
+ edition, ports, and age.
332
+
333
+ \b
334
+ Examples:
335
+ # List running containers
336
+ iris-devtester container list
337
+
338
+ # List all containers (including stopped)
339
+ iris-devtester container list --all
340
+
341
+ # JSON output for scripting
342
+ iris-devtester container list --format json
343
+ """
344
+ from datetime import datetime
345
+
346
+ import docker
347
+
348
+ try:
349
+ client = docker.from_env()
350
+
351
+ # Find IRIS containers (by image name patterns)
352
+ iris_patterns = [
353
+ "iris-community",
354
+ "intersystems/iris",
355
+ "caretdev/iris",
356
+ "intersystemsdc/iris",
357
+ ]
358
+
359
+ containers = client.containers.list(all=show_all)
360
+ iris_containers = []
361
+
362
+ for container in containers:
363
+ image_name = (
364
+ container.image.tags[0] if container.image.tags else str(container.image.id)[:12]
365
+ )
366
+
367
+ # Check if this is an IRIS container
368
+ is_iris = any(pattern in image_name.lower() for pattern in iris_patterns)
369
+ if not is_iris:
370
+ continue
371
+
372
+ # Determine edition from image name
373
+ if "light" in image_name.lower():
374
+ edition = "light"
375
+ elif "community" in image_name.lower():
376
+ edition = "community"
377
+ else:
378
+ edition = "enterprise"
379
+
380
+ # Get port mappings
381
+ ports = container.attrs.get("NetworkSettings", {}).get("Ports", {})
382
+ port_str = "-"
383
+ if ports and ports.get("1972/tcp"):
384
+ host_port = ports["1972/tcp"][0]["HostPort"]
385
+ port_str = f"{host_port}->1972"
386
+
387
+ # Calculate age
388
+ created = container.attrs.get("Created", "")
389
+ age_str = "unknown"
390
+ if created:
391
+ try:
392
+ # Parse ISO format timestamp
393
+ created_dt = datetime.fromisoformat(created.replace("Z", "+00:00"))
394
+ now = datetime.now(created_dt.tzinfo)
395
+ delta = now - created_dt
396
+ if delta.days > 0:
397
+ age_str = f"{delta.days}d"
398
+ elif delta.seconds > 3600:
399
+ age_str = f"{delta.seconds // 3600}h"
400
+ else:
401
+ age_str = f"{delta.seconds // 60}m"
402
+ except Exception:
403
+ pass
404
+
405
+ iris_containers.append(
406
+ {
407
+ "name": container.name,
408
+ "edition": edition,
409
+ "status": container.status,
410
+ "ports": port_str,
411
+ "age": age_str,
412
+ "image": image_name,
413
+ }
414
+ )
415
+
416
+ if output_format == "json":
417
+ import json as json_module
418
+
419
+ click.echo(json_module.dumps(iris_containers, indent=2))
420
+ else:
421
+ # Table format
422
+ if not iris_containers:
423
+ click.echo("No IRIS containers found.")
424
+ if not show_all:
425
+ click.echo("Use --all to include stopped containers.")
426
+ else:
427
+ # Print header
428
+ click.echo(f"{'NAME':<20} {'EDITION':<12} {'STATUS':<10} {'PORTS':<15} {'AGE':<6}")
429
+ click.echo("-" * 65)
430
+
431
+ for c in iris_containers:
432
+ status_color = "green" if c["status"] == "running" else "yellow"
433
+ click.echo(
434
+ f"{c['name']:<20} "
435
+ f"{c['edition']:<12} "
436
+ f"{click.style(c['status'], fg=status_color):<19} "
437
+ f"{c['ports']:<15} "
438
+ f"{c['age']:<6}"
439
+ )
440
+
441
+ except docker.errors.DockerException as e:
442
+ progress.print_error(f"Docker error: {e}")
443
+ ctx.exit(1)
444
+ except Exception as e:
445
+ progress.print_error(f"Error listing containers: {e}")
446
+ ctx.exit(1)
447
+
448
+
231
449
  @container_group.command(name="start")
232
450
  @click.argument("container_name", required=False, default="iris_db")
233
451
  @click.option(
@@ -613,7 +831,7 @@ def remove(ctx, container_name, force, volumes):
613
831
 
614
832
 
615
833
  @container_group.command(name="reset-password")
616
- @click.argument("container_name")
834
+ @click.argument("container_name", required=False, default="iris_db")
617
835
  @click.option("--user", default="_SYSTEM", help="Username to reset password for (default: _SYSTEM)")
618
836
  @click.option("--password", default="SYS", help="New password (default: SYS)")
619
837
  @click.option(
@@ -679,7 +897,7 @@ def reset_password_cmd(ctx, container_name, user, password, port):
679
897
 
680
898
 
681
899
  @container_group.command(name="test-connection")
682
- @click.argument("container_name")
900
+ @click.argument("container_name", required=False, default="iris_db")
683
901
  @click.option(
684
902
  "--namespace", default="USER", help="IRIS namespace to test connection to (default: USER)"
685
903
  )
@@ -768,7 +986,7 @@ def test_connection_cmd(ctx, container_name, namespace, username, password):
768
986
 
769
987
 
770
988
  @container_group.command(name="enable-callin")
771
- @click.argument("container_name")
989
+ @click.argument("container_name", required=False, default="iris_db")
772
990
  @click.option(
773
991
  "--timeout", type=int, default=30, help="Timeout in seconds for docker commands (default: 30)"
774
992
  )
@@ -808,9 +1026,6 @@ def enable_callin(ctx, container_name, timeout):
808
1026
  except (ImportError, ModuleNotFoundError) as e:
809
1027
  progress.print_error(f"enable_callin utility not available: {e}")
810
1028
  ctx.exit(1)
811
- except (click.exceptions.Exit, SystemExit, KeyboardInterrupt):
812
- # Let Click handle these - don't catch them
813
- raise
814
1029
  except Exception as e:
815
1030
  progress.print_error(f"Failed to enable CallIn: {e}")
816
1031
  ctx.exit(1)