opencode-conf-man 1.1.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.
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.4
2
+ Name: opencode-conf-man
3
+ Version: 1.1.0
4
+ Summary: 统一配置管理服务 - 版本的唯一真相来源
5
+ Author-email: conf-man Team <team@conf-man.dev>
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: pyyaml>=5.4
10
+ Requires-Dist: click>=8.0
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=7.0; extra == "dev"
13
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
14
+
15
+ # conf-man
16
+
17
+ 配置管理器 - 版本的"唯一真相来源"
18
+
19
+ ## 职责
20
+
21
+ | 职责 | 说明 |
22
+ |------|------|
23
+ | **版本登记** | 记录每个测试通过的版本 |
24
+ | **代码快照** | 保存当时的Git commit hash |
25
+ | **依赖锁定** | 记录所有依赖的精确版本 |
26
+ | **发布协调** | 触发发布、确认完成 |
27
+ | **回滚能力** | 能找回之前的版本 |
28
+
29
+ ## 发布流程
30
+
31
+ ```
32
+ oc-collab → test-agent → conf-man → pm-agent → 用户
33
+ ```
34
+
35
+ ## 命令
36
+
37
+ ```bash
38
+ # 登记版本
39
+ conf-man register --version 2.3.0 --manifest manifest.yaml --test-report test_report.yaml
40
+
41
+ # 查询版本
42
+ conf-man list # 列出所有版本
43
+ conf-man show 2.3.0 # 显示版本详情
44
+
45
+ # 触发发布
46
+ conf-man release --version 2.3.0
47
+ ```
48
+
49
+ ## 目录结构
50
+
51
+ ```
52
+ conf-man/
53
+ ├── versions/ # 版本记录存储
54
+ │ └── v{x.y.z}.yaml
55
+ ├── src/ # 源代码
56
+ ├── state/ # 状态文件
57
+ ├── tests/ # 测试
58
+ ├── skills/ # Skill
59
+ ├── docs/ # 文档
60
+ └── config/ # 配置
61
+ ```
62
+
63
+ ## 相关文档
64
+
65
+ - 发布流程: `../HQ/docs/04-releases/RELEASE_PROCESS.md`
66
+ - 发布管理Skill: `../HQ/skills/hq_release_management/content.md`
67
+ - 本系统Release Guide: `skills/conf_man_release_guide/content.md`
68
+ - 本系统Release Guide: `skills/conf_man_release_guide/content.md`
@@ -0,0 +1,54 @@
1
+ # conf-man
2
+
3
+ 配置管理器 - 版本的"唯一真相来源"
4
+
5
+ ## 职责
6
+
7
+ | 职责 | 说明 |
8
+ |------|------|
9
+ | **版本登记** | 记录每个测试通过的版本 |
10
+ | **代码快照** | 保存当时的Git commit hash |
11
+ | **依赖锁定** | 记录所有依赖的精确版本 |
12
+ | **发布协调** | 触发发布、确认完成 |
13
+ | **回滚能力** | 能找回之前的版本 |
14
+
15
+ ## 发布流程
16
+
17
+ ```
18
+ oc-collab → test-agent → conf-man → pm-agent → 用户
19
+ ```
20
+
21
+ ## 命令
22
+
23
+ ```bash
24
+ # 登记版本
25
+ conf-man register --version 2.3.0 --manifest manifest.yaml --test-report test_report.yaml
26
+
27
+ # 查询版本
28
+ conf-man list # 列出所有版本
29
+ conf-man show 2.3.0 # 显示版本详情
30
+
31
+ # 触发发布
32
+ conf-man release --version 2.3.0
33
+ ```
34
+
35
+ ## 目录结构
36
+
37
+ ```
38
+ conf-man/
39
+ ├── versions/ # 版本记录存储
40
+ │ └── v{x.y.z}.yaml
41
+ ├── src/ # 源代码
42
+ ├── state/ # 状态文件
43
+ ├── tests/ # 测试
44
+ ├── skills/ # Skill
45
+ ├── docs/ # 文档
46
+ └── config/ # 配置
47
+ ```
48
+
49
+ ## 相关文档
50
+
51
+ - 发布流程: `../HQ/docs/04-releases/RELEASE_PROCESS.md`
52
+ - 发布管理Skill: `../HQ/skills/hq_release_management/content.md`
53
+ - 本系统Release Guide: `skills/conf_man_release_guide/content.md`
54
+ - 本系统Release Guide: `skills/conf_man_release_guide/content.md`
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.4
2
+ Name: opencode-conf-man
3
+ Version: 1.1.0
4
+ Summary: 统一配置管理服务 - 版本的唯一真相来源
5
+ Author-email: conf-man Team <team@conf-man.dev>
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: pyyaml>=5.4
10
+ Requires-Dist: click>=8.0
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=7.0; extra == "dev"
13
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
14
+
15
+ # conf-man
16
+
17
+ 配置管理器 - 版本的"唯一真相来源"
18
+
19
+ ## 职责
20
+
21
+ | 职责 | 说明 |
22
+ |------|------|
23
+ | **版本登记** | 记录每个测试通过的版本 |
24
+ | **代码快照** | 保存当时的Git commit hash |
25
+ | **依赖锁定** | 记录所有依赖的精确版本 |
26
+ | **发布协调** | 触发发布、确认完成 |
27
+ | **回滚能力** | 能找回之前的版本 |
28
+
29
+ ## 发布流程
30
+
31
+ ```
32
+ oc-collab → test-agent → conf-man → pm-agent → 用户
33
+ ```
34
+
35
+ ## 命令
36
+
37
+ ```bash
38
+ # 登记版本
39
+ conf-man register --version 2.3.0 --manifest manifest.yaml --test-report test_report.yaml
40
+
41
+ # 查询版本
42
+ conf-man list # 列出所有版本
43
+ conf-man show 2.3.0 # 显示版本详情
44
+
45
+ # 触发发布
46
+ conf-man release --version 2.3.0
47
+ ```
48
+
49
+ ## 目录结构
50
+
51
+ ```
52
+ conf-man/
53
+ ├── versions/ # 版本记录存储
54
+ │ └── v{x.y.z}.yaml
55
+ ├── src/ # 源代码
56
+ ├── state/ # 状态文件
57
+ ├── tests/ # 测试
58
+ ├── skills/ # Skill
59
+ ├── docs/ # 文档
60
+ └── config/ # 配置
61
+ ```
62
+
63
+ ## 相关文档
64
+
65
+ - 发布流程: `../HQ/docs/04-releases/RELEASE_PROCESS.md`
66
+ - 发布管理Skill: `../HQ/skills/hq_release_management/content.md`
67
+ - 本系统Release Guide: `skills/conf_man_release_guide/content.md`
68
+ - 本系统Release Guide: `skills/conf_man_release_guide/content.md`
@@ -0,0 +1,16 @@
1
+ README.md
2
+ pyproject.toml
3
+ opencode_conf_man.egg-info/PKG-INFO
4
+ opencode_conf_man.egg-info/SOURCES.txt
5
+ opencode_conf_man.egg-info/dependency_links.txt
6
+ opencode_conf_man.egg-info/entry_points.txt
7
+ opencode_conf_man.egg-info/requires.txt
8
+ opencode_conf_man.egg-info/top_level.txt
9
+ src/__init__.py
10
+ src/cli.py
11
+ src/config_provider.py
12
+ src/environment_config.py
13
+ tests/test_cli.py
14
+ tests/test_config_provider.py
15
+ tests/test_e2e.py
16
+ tests/test_environment_config.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ conf-man = src.__init__:main
@@ -0,0 +1,6 @@
1
+ pyyaml>=5.4
2
+ click>=8.0
3
+
4
+ [dev]
5
+ pytest>=7.0
6
+ pytest-cov>=4.0
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=45", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "opencode-conf-man"
7
+ version = "1.1.0"
8
+ description = "统一配置管理服务 - 版本的唯一真相来源"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "conf-man Team", email = "team@conf-man.dev"}
14
+ ]
15
+ dependencies = [
16
+ "pyyaml>=5.4",
17
+ "click>=8.0",
18
+ ]
19
+
20
+ [project.optional-dependencies]
21
+ dev = [
22
+ "pytest>=7.0",
23
+ "pytest-cov>=4.0",
24
+ ]
25
+
26
+ [project.scripts]
27
+ conf-man = "src.__init__:main"
28
+
29
+ [tool.setuptools]
30
+ packages = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env python3
2
+ """conf-man CLI entry point."""
3
+
4
+ import click
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ VERSION = "1.1.0"
9
+
10
+ try:
11
+ from config_provider import ConfManProvider, get_provider
12
+ from environment_config import EnvironmentConfig
13
+ except ImportError:
14
+ from .config_provider import ConfManProvider, get_provider
15
+ from .environment_config import EnvironmentConfig
16
+
17
+ __all__ = ['ConfManProvider', 'EnvironmentConfig', 'get_provider', 'VERSION', 'cli', 'main']
18
+
19
+
20
+ @click.group()
21
+ @click.version_option(version=VERSION)
22
+ def cli():
23
+ """conf-man: 配置管理器 - 版本的"唯一真相来源" """
24
+ pass
25
+
26
+
27
+ @cli.command()
28
+ def init():
29
+ """初始化conf-man"""
30
+ click.echo(f"conf-man v{VERSION}")
31
+ click.echo("配置管理器已初始化")
32
+ click.echo("\n目录结构:")
33
+ click.echo(" versions/ - 版本记录")
34
+ click.echo(" state/ - 状态文件")
35
+ click.echo(" skills/ - Skill文档")
36
+
37
+
38
+ @cli.command()
39
+ @click.argument("version")
40
+ @click.option("--manifest", required=True, help="版本清单文件")
41
+ @click.option("--test-report", required=True, help="测试报告文件")
42
+ def register(version, manifest, test_report):
43
+ """登记新版本"""
44
+ click.echo(f"登记版本 {version}...")
45
+ # TODO: 实现版本登记逻辑
46
+ click.echo(f"版本 {version} 登记完成")
47
+
48
+
49
+ @cli.command()
50
+ def list():
51
+ """列出所有版本"""
52
+ # TODO: 实现版本列表
53
+ click.echo("暂无登记版本")
54
+
55
+
56
+ @cli.command()
57
+ @click.argument("version")
58
+ def show(version):
59
+ """显示版本详情"""
60
+ # TODO: 实现版本详情
61
+ click.echo(f"版本 {version} 详情")
62
+
63
+
64
+ @cli.command()
65
+ @click.argument("version")
66
+ def release(version):
67
+ """触发发布"""
68
+ # TODO: 实现发布逻辑
69
+ click.echo(f"触发发布 {version}...")
70
+
71
+
72
+ def main():
73
+ cli()
74
+
75
+
76
+ if __name__ == "__main__":
77
+ main()
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python3
2
+ """conf-man CLI entry point."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).parent.parent))
8
+
9
+ from src import main
10
+
11
+ if __name__ == "__main__":
12
+ main()
@@ -0,0 +1,118 @@
1
+ from pathlib import Path
2
+ from typing import Optional, Dict, Any
3
+ import os
4
+
5
+ DEFAULT_VERSION = "1.0.0"
6
+
7
+
8
+ class ConfManProvider:
9
+ """Configuration provider implementation - avoids conflict with oc-collab's LocalConfigProvider"""
10
+
11
+ def __init__(self, config_path: Optional[str] = None, base_dir: Optional[Path] = None):
12
+ self._base_dir = base_dir or Path.cwd()
13
+ self._config = self._load_config(config_path)
14
+ self._version = DEFAULT_VERSION
15
+
16
+ def _load_config(self, config_path: Optional[str]) -> Dict[str, Any]:
17
+ """Load configuration with fallback to defaults"""
18
+ if config_path:
19
+ config_file = Path(config_path)
20
+ if config_file.exists():
21
+ base_dir = config_file.parent.parent
22
+ self._base_dir = base_dir
23
+ import yaml
24
+ with open(config_file, 'r') as f:
25
+ return yaml.safe_load(f) or {}
26
+
27
+ return {}
28
+
29
+ def _get_path(self, key: str, default: str) -> str:
30
+ """Get path from config with default fallback"""
31
+ paths = self._config.get('paths', {})
32
+ return str(self._base_dir / paths.get(key, default))
33
+
34
+ def _get_file(self, key: str, default: str) -> str:
35
+ """Get file path from config with default fallback"""
36
+ files = self._config.get('files', {})
37
+ return str(self._base_dir / files.get(key, default))
38
+
39
+ def _get_config_file(self, key: str, default: str) -> str:
40
+ """Get config file path from config with default fallback"""
41
+ configs = self._config.get('configs', {})
42
+ config_dir = self._get_path('config_dir', 'config')
43
+ return str(Path(config_dir) / configs.get(key, default))
44
+
45
+ def get_data_dir(self) -> str:
46
+ return self._get_path('data_dir', 'state')
47
+
48
+ def get_config_dir(self) -> str:
49
+ return self._get_path('config_dir', 'config')
50
+
51
+ def get_log_dir(self) -> str:
52
+ return self._get_path('log_dir', 'logs')
53
+
54
+ def get_temp_dir(self) -> str:
55
+ return self._get_path('temp_dir', 'tmp')
56
+
57
+ def get_todo_db_path(self) -> str:
58
+ return self._get_file('todo_db', 'todos.db')
59
+
60
+ def get_state_file_path(self) -> str:
61
+ return self._get_file('state_file', 'project_state.yaml')
62
+
63
+ def get_lock_file_path(self, name: str) -> str:
64
+ data_dir = self.get_data_dir()
65
+ return str(Path(data_dir) / f"{name}.lock")
66
+
67
+ def get_agent_status_db_path(self) -> str:
68
+ return self._get_file('agent_status_db', 'agent_status.db')
69
+
70
+ def get_session_dir(self) -> str:
71
+ return self._get_file('session_dir', 'sessions')
72
+
73
+ def get_adhoc_todos_path(self) -> str:
74
+ return self._get_file('adhoc_todos', 'agent_adhoc_todos.yaml')
75
+
76
+ def get_identity_file_path(self) -> str:
77
+ return self._get_file('identity_file', 'agent.identity')
78
+
79
+ def get_pid_file_path(self) -> str:
80
+ return self._get_file('pid_file', 'agent.pid')
81
+
82
+ def get_opencode_db_path(self) -> str:
83
+ return self._get_file('opencode_db', '.opencode/opencode.db')
84
+
85
+ def get_agents_config_path(self) -> str:
86
+ return self._get_config_file('agents', 'agents.yaml')
87
+
88
+ def get_git_sync_config_path(self) -> str:
89
+ return self._get_config_file('git_sync', 'git_sync.yaml')
90
+
91
+ def get_notification_config_path(self) -> str:
92
+ return self._get_config_file('notification', 'notification.yaml')
93
+
94
+ def get_skill_index_path(self) -> str:
95
+ return self._get_config_file('skill_index', 'skill_index.yaml')
96
+
97
+ def get_file_owners_path(self) -> str:
98
+ return self._get_config_file('file_owners', 'file_owners.yaml')
99
+
100
+ def get_full_path(self, relative_path: str, base_path: Optional[Path] = None) -> Path:
101
+ """Get full path by joining base path with relative path"""
102
+ base = base_path or self._base_dir
103
+ return base / relative_path
104
+
105
+ def get_version(self) -> str:
106
+ """Get conf-man version"""
107
+ return self._version
108
+
109
+
110
+ _provider_instance: Optional[ConfManProvider] = None
111
+
112
+
113
+ def get_provider(config_path: Optional[str] = None, base_dir: Optional[Path] = None) -> ConfManProvider:
114
+ """Get or create singleton ConfManProvider instance"""
115
+ global _provider_instance
116
+ if _provider_instance is None:
117
+ _provider_instance = ConfManProvider(config_path, base_dir)
118
+ return _provider_instance
@@ -0,0 +1,39 @@
1
+ import os
2
+ from typing import Optional, TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING:
5
+ from config_provider import ConfManProvider
6
+ else:
7
+ try:
8
+ from config_provider import ConfManProvider
9
+ except ImportError:
10
+ ConfManProvider = None
11
+
12
+
13
+ class EnvironmentConfig:
14
+ """Environment configuration implementation"""
15
+
16
+ def __init__(self, config_provider: Optional["ConfManProvider"] = None):
17
+ self._config = config_provider
18
+ self._env = os.getenv("CONF_MAN_ENV", "dev")
19
+
20
+ def get_environment(self) -> str:
21
+ """Get current environment (dev/test/prod)"""
22
+ env_from_config = None
23
+ if self._config:
24
+ env_from_config = self._config._config.get('environment', {}).get('mode')
25
+
26
+ return env_from_config or self._env
27
+
28
+ def is_test_mode(self) -> bool:
29
+ """Check if running in test mode"""
30
+ test_env = os.getenv("CONF_MAN_TEST", "")
31
+ if test_env.lower() in ('1', 'true', 'yes'):
32
+ return True
33
+
34
+ if self._config:
35
+ env_config = self._config._config.get('environment', {})
36
+ if env_config.get('mode') == 'test':
37
+ return True
38
+
39
+ return self._env == 'test'
@@ -0,0 +1,65 @@
1
+ import pytest
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ sys.path.insert(0, str(Path(__file__).parent.parent / 'src'))
6
+
7
+ from __init__ import cli, VERSION
8
+
9
+
10
+ class TestCli:
11
+ """Test CLI module"""
12
+
13
+ def test_cli_version(self, runner):
14
+ """Test CLI version"""
15
+ result = runner.invoke(cli, ['--version'])
16
+ assert result.exit_code == 0
17
+ assert VERSION in result.output
18
+
19
+ def test_cli_help(self, runner):
20
+ """Test CLI help"""
21
+ result = runner.invoke(cli, ['--help'])
22
+ assert result.exit_code == 0
23
+ assert 'conf-man' in result.output
24
+
25
+ def test_init_command(self, runner):
26
+ """Test init command"""
27
+ result = runner.invoke(cli, ['init'])
28
+ assert result.exit_code == 0
29
+ assert 'conf-man' in result.output
30
+
31
+ def test_list_command(self, runner):
32
+ """Test list command"""
33
+ result = runner.invoke(cli, ['list'])
34
+ assert result.exit_code == 0
35
+
36
+ def test_show_command(self, runner):
37
+ """Test show command"""
38
+ result = runner.invoke(cli, ['show', 'v1.0.0'])
39
+ assert result.exit_code == 0
40
+ assert 'v1.0.0' in result.output
41
+
42
+ def test_register_command_missing_options(self, runner):
43
+ """Test register command with missing options"""
44
+ result = runner.invoke(cli, ['register', 'v1.0.0'])
45
+ assert result.exit_code != 0
46
+
47
+ def test_register_command(self, runner):
48
+ """Test register command"""
49
+ result = runner.invoke(cli, ['register', 'v1.0.0',
50
+ '--manifest', 'manifest.yaml',
51
+ '--test-report', 'report.yaml'])
52
+ assert result.exit_code == 0
53
+
54
+ def test_release_command(self, runner):
55
+ """Test release command"""
56
+ result = runner.invoke(cli, ['release', 'v1.0.0'])
57
+ assert result.exit_code == 0
58
+ assert 'v1.0.0' in result.output
59
+
60
+
61
+ @pytest.fixture
62
+ def runner():
63
+ """Create CLI runner"""
64
+ from click.testing import CliRunner
65
+ return CliRunner()