monoco-toolkit 0.2.5__py3-none-any.whl → 0.2.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. monoco/core/agent/adapters.py +24 -1
  2. monoco/core/config.py +77 -17
  3. monoco/core/integrations.py +8 -0
  4. monoco/core/lsp.py +7 -0
  5. monoco/core/output.py +8 -1
  6. monoco/core/resources/zh/SKILL.md +6 -7
  7. monoco/core/setup.py +8 -0
  8. monoco/features/i18n/resources/zh/SKILL.md +5 -5
  9. monoco/features/issue/commands.py +179 -55
  10. monoco/features/issue/core.py +263 -124
  11. monoco/features/issue/domain/__init__.py +0 -0
  12. monoco/features/issue/domain/lifecycle.py +126 -0
  13. monoco/features/issue/domain/models.py +170 -0
  14. monoco/features/issue/domain/parser.py +223 -0
  15. monoco/features/issue/domain/workspace.py +104 -0
  16. monoco/features/issue/engine/__init__.py +22 -0
  17. monoco/features/issue/engine/config.py +172 -0
  18. monoco/features/issue/engine/machine.py +185 -0
  19. monoco/features/issue/engine/models.py +18 -0
  20. monoco/features/issue/linter.py +118 -12
  21. monoco/features/issue/lsp/__init__.py +3 -0
  22. monoco/features/issue/lsp/definition.py +72 -0
  23. monoco/features/issue/models.py +27 -9
  24. monoco/features/issue/resources/en/AGENTS.md +5 -0
  25. monoco/features/issue/resources/en/SKILL.md +26 -2
  26. monoco/features/issue/resources/zh/AGENTS.md +5 -0
  27. monoco/features/issue/resources/zh/SKILL.md +34 -10
  28. monoco/features/issue/validator.py +252 -66
  29. monoco/features/spike/core.py +5 -22
  30. monoco/features/spike/resources/zh/SKILL.md +2 -2
  31. monoco/main.py +2 -26
  32. monoco_toolkit-0.2.8.dist-info/METADATA +136 -0
  33. {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.8.dist-info}/RECORD +36 -30
  34. monoco/features/agent/commands.py +0 -166
  35. monoco/features/agent/doctor.py +0 -30
  36. monoco/features/pty/core.py +0 -185
  37. monoco/features/pty/router.py +0 -138
  38. monoco/features/pty/server.py +0 -56
  39. monoco_toolkit-0.2.5.dist-info/METADATA +0 -93
  40. {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.8.dist-info}/WHEEL +0 -0
  41. {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.8.dist-info}/entry_points.txt +0 -0
  42. {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.8.dist-info}/licenses/LICENSE +0 -0
@@ -21,6 +21,16 @@ class BaseCLIClient:
21
21
 
22
22
  def _build_prompt(self, prompt: str, context_files: List[Path]) -> str:
23
23
  """Concatenate prompt and context files."""
24
+ # Inject Language Rule
25
+ try:
26
+ from monoco.core.config import get_config
27
+ settings = get_config()
28
+ lang = settings.i18n.source_lang
29
+ if lang:
30
+ prompt = f"{prompt}\n\n[SYSTEM: LANGUAGE CONSTRAINT]\nThe project source language is '{lang}'. You MUST use '{lang}' for all thinking and reporting unless explicitly instructed otherwise."
31
+ except Exception:
32
+ pass
33
+
24
34
  full_prompt = [prompt]
25
35
  if context_files:
26
36
  full_prompt.append("\n\n--- CONTEXT FILES ---")
@@ -93,10 +103,23 @@ class QwenClient(BaseCLIClient, AgentClient):
93
103
  return await self._run_command([self._executable, full_prompt])
94
104
 
95
105
 
106
+ class KimiClient(BaseCLIClient, AgentClient):
107
+ """Adapter for Moonshot Kimi CLI."""
108
+
109
+ def __init__(self):
110
+ super().__init__("kimi")
111
+
112
+ async def execute(self, prompt: str, context_files: List[Path] = []) -> str:
113
+ full_prompt = self._build_prompt(prompt, context_files)
114
+ # Usage: kimi "prompt"
115
+ return await self._run_command([self._executable, full_prompt])
116
+
117
+
96
118
  _ADAPTERS = {
97
119
  "gemini": GeminiClient,
98
120
  "claude": ClaudeClient,
99
- "qwen": QwenClient
121
+ "qwen": QwenClient,
122
+ "kimi": KimiClient
100
123
  }
101
124
 
102
125
  def get_agent_client(name: str) -> AgentClient:
monoco/core/config.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  import yaml
3
3
  from pathlib import Path
4
- from typing import Optional, Dict, Any, Callable, Awaitable
4
+ from typing import Optional, Dict, Any, Callable, Awaitable, List
5
5
  from enum import Enum
6
6
  from pydantic import BaseModel, Field
7
7
 
@@ -10,7 +10,7 @@ import asyncio
10
10
  from watchdog.observers import Observer
11
11
  from watchdog.events import FileSystemEventHandler
12
12
 
13
- from monoco.core.integrations import AgentIntegration
13
+
14
14
 
15
15
  logger = logging.getLogger("monoco.core.config")
16
16
 
@@ -46,15 +46,68 @@ class TelemetryConfig(BaseModel):
46
46
  """Configuration for Telemetry."""
47
47
  enabled: Optional[bool] = Field(default=None, description="Whether telemetry is enabled")
48
48
 
49
- class AgentConfig(BaseModel):
50
- """Configuration for Agent Environment Integration."""
51
- targets: Optional[list[str]] = Field(default=None, description="Specific target files to inject into (e.g. .cursorrules)")
52
- framework: Optional[str] = Field(default=None, description="Manually specified agent framework (cursor, windsurf, etc.)")
53
- includes: Optional[list[str]] = Field(default=None, description="List of specific features to include in injection")
54
- integrations: Optional[Dict[str, "AgentIntegration"]] = Field(
55
- default=None,
56
- description="Custom agent framework integrations (overrides defaults from monoco.core.integrations)"
57
- )
49
+
50
+
51
+ class IssueTypeConfig(BaseModel):
52
+ name: str
53
+ label: str
54
+ prefix: str
55
+ folder: str
56
+ description: Optional[str] = None
57
+
58
+ class TransitionConfig(BaseModel):
59
+ name: str
60
+ label: str
61
+ icon: Optional[str] = None
62
+ from_status: Optional[str] = None
63
+ from_stage: Optional[str] = None
64
+ to_status: str
65
+ to_stage: Optional[str] = None
66
+ required_solution: Optional[str] = None
67
+ description: str = ""
68
+ command_template: Optional[str] = None
69
+
70
+ class IssueSchemaConfig(BaseModel):
71
+ types: List[IssueTypeConfig] = Field(default_factory=list)
72
+ statuses: List[str] = Field(default_factory=list)
73
+ stages: List[str] = Field(default_factory=list)
74
+ solutions: List[str] = Field(default_factory=list)
75
+ workflows: List[TransitionConfig] = Field(default_factory=list)
76
+
77
+ def merge(self, other: "IssueSchemaConfig") -> "IssueSchemaConfig":
78
+ if not other:
79
+ return self
80
+
81
+ # Types: merge by name
82
+ if other.types:
83
+ type_map = {t.name: t for t in self.types}
84
+ for ot in other.types:
85
+ type_map[ot.name] = ot
86
+ self.types = list(type_map.values())
87
+
88
+ # Statuses: replace if provided
89
+ if other.statuses:
90
+ self.statuses = other.statuses
91
+
92
+ # Stages: replace if provided
93
+ if other.stages:
94
+ self.stages = other.stages
95
+
96
+ # Solutions: replace if provided
97
+ if other.solutions:
98
+ self.solutions = other.solutions
99
+
100
+ # Workflows (Transitions): merge by name
101
+ if other.workflows:
102
+ wf_map = {w.name: w for w in self.workflows}
103
+ for ow in other.workflows:
104
+ wf_map[ow.name] = ow
105
+ self.workflows = list(wf_map.values())
106
+
107
+ return self
108
+
109
+ class StateMachineConfig(BaseModel):
110
+ transitions: List[TransitionConfig]
58
111
 
59
112
  class MonocoConfig(BaseModel):
60
113
  """
@@ -67,7 +120,8 @@ class MonocoConfig(BaseModel):
67
120
  i18n: I18nConfig = Field(default_factory=I18nConfig)
68
121
  ui: UIConfig = Field(default_factory=UIConfig)
69
122
  telemetry: TelemetryConfig = Field(default_factory=TelemetryConfig)
70
- agent: AgentConfig = Field(default_factory=AgentConfig)
123
+
124
+ issue: IssueSchemaConfig = Field(default_factory=IssueSchemaConfig)
71
125
 
72
126
  @staticmethod
73
127
  def _deep_merge(base: Dict[str, Any], update: Dict[str, Any]) -> Dict[str, Any]:
@@ -179,15 +233,21 @@ def get_config_path(scope: ConfigScope, project_root: Optional[str] = None) -> P
179
233
  return cwd / ".monoco" / "project.yaml"
180
234
 
181
235
  def find_monoco_root(start_path: Optional[Path] = None) -> Path:
182
- """Recursively find the .monoco directory upwards."""
236
+ """
237
+ Find the Monoco Workspace root.
238
+ Strictly restricted to checking the current directory (or its parent if CWD is .monoco).
239
+ Recursive upward lookup is disabled per FIX-0009.
240
+ """
183
241
  current = (start_path or Path.cwd()).resolve()
184
- # Check if we are inside a .monoco folder (unlikely but possible)
242
+
243
+ # Check if we are inside a .monoco folder
185
244
  if current.name == ".monoco":
186
245
  return current.parent
187
246
 
188
- for parent in [current] + list(current.parents):
189
- if (parent / ".monoco").exists():
190
- return parent
247
+ # Check if current directory has .monoco
248
+ if (current / ".monoco").exists():
249
+ return current
250
+
191
251
  return current
192
252
 
193
253
  def load_raw_config(scope: ConfigScope, project_root: Optional[str] = None) -> Dict[str, Any]:
@@ -110,6 +110,14 @@ DEFAULT_INTEGRATIONS: Dict[str, AgentIntegration] = {
110
110
  bin_name="qwen",
111
111
  version_cmd="--version",
112
112
  ),
113
+ "kimi": AgentIntegration(
114
+ key="kimi",
115
+ name="Kimi CLI",
116
+ system_prompt_file="KIMI.md",
117
+ skill_root_dir=".kimi/skills/",
118
+ bin_name="kimi",
119
+ version_cmd="--version",
120
+ ),
113
121
  "agent": AgentIntegration(
114
122
  key="agent",
115
123
  name="Antigravity",
monoco/core/lsp.py CHANGED
@@ -24,6 +24,13 @@ class Range(BaseModel):
24
24
  def __repr__(self):
25
25
  return f"{self.start.line}:{self.start.character}-{self.end.line}:{self.end.character}"
26
26
 
27
+ class Location(BaseModel):
28
+ """
29
+ Represents a location inside a resource, such as a line of code inside a text file.
30
+ """
31
+ uri: str
32
+ range: Range
33
+
27
34
  class DiagnosticSeverity(IntEnum):
28
35
  Error = 1
29
36
  Warning = 2
monoco/core/output.py CHANGED
@@ -63,8 +63,15 @@ class OutputManager:
63
63
  print(json.dumps([item.model_dump(mode='json', exclude_none=True) for item in data], separators=(',', ':')))
64
64
  else:
65
65
  # Fallback for dicts/lists/primitives
66
+ def _encoder(obj):
67
+ if isinstance(obj, BaseModel):
68
+ return obj.model_dump(mode='json', exclude_none=True)
69
+ if hasattr(obj, 'value'): # Enum support
70
+ return obj.value
71
+ return str(obj)
72
+
66
73
  try:
67
- print(json.dumps(data, separators=(',', ':'), default=str))
74
+ print(json.dumps(data, separators=(',', ':'), default=_encoder))
68
75
  except TypeError:
69
76
  print(str(data))
70
77
 
@@ -9,11 +9,11 @@ Monoco Toolkit 的核心功能和命令。
9
9
 
10
10
  ## 概述
11
11
 
12
- Monoco 是一个开发者生产力工具包,提供:
12
+ Monoco 是一个开发者生产力工具包,提供:
13
13
 
14
- - **项目初始化**:标准化的项目结构
15
- - **配置管理**:全局和项目级别的配置
16
- - **工作空间管理**:多项目设置
14
+ - **项目初始化**: 标准化的项目结构
15
+ - **配置管理**: 全局和项目级别的配置
16
+ - **工作空间管理**: 多项目设置
17
17
 
18
18
  ## 核心命令
19
19
 
@@ -34,7 +34,6 @@ Monoco 是一个开发者生产力工具包,提供:
34
34
  ### Agent 集成
35
35
 
36
36
  - **`monoco sync`**: 与 agent 环境同步
37
-
38
37
  - 将系统提示注入到 agent 配置文件(GEMINI.md, CLAUDE.md 等)
39
38
  - 分发 skills 到 agent 框架目录
40
39
  - 遵循 `i18n.source_lang` 的语言配置
@@ -45,12 +44,12 @@ Monoco 是一个开发者生产力工具包,提供:
45
44
 
46
45
  ## 配置结构
47
46
 
48
- 配置以 YAML 格式存储在:
47
+ 配置以 YAML 格式存储在:
49
48
 
50
49
  - **全局**: `~/.monoco/config.yaml`
51
50
  - **项目**: `.monoco/config.yaml`
52
51
 
53
- 关键配置段:
52
+ 关键配置段:
54
53
 
55
54
  - `core`: 编辑器、日志级别、作者
56
55
  - `paths`: 目录路径(issues, spikes, specs)
monoco/core/setup.py CHANGED
@@ -258,6 +258,14 @@ def init_cli(
258
258
  (cwd / "Issues").mkdir(exist_ok=True)
259
259
  (cwd / ".references").mkdir(exist_ok=True)
260
260
 
261
+ # Initialize Agent Resources
262
+ try:
263
+ from monoco.features.agent.core import init_agent_resources
264
+ init_agent_resources(cwd)
265
+ console.print(f"[dim] - Agent Resources: .monoco/actions/*.prompty[/dim]")
266
+ except Exception as e:
267
+ console.print(f"[yellow]Warning: Failed to init agent resources: {e}[/yellow]")
268
+
261
269
  console.print("\n[bold green]✓ Monoco Project Initialized![/bold green]")
262
270
  console.print(f"Access configured! issues will be created as [bold]{project_key}-XXX[/bold]")
263
271
 
@@ -9,7 +9,7 @@ description: 文档国际化质量控制。确保多语言文档保持同步。
9
9
 
10
10
  ## 概述
11
11
 
12
- I18n 功能提供:
12
+ I18n 功能提供:
13
13
 
14
14
  - **自动扫描**缺失的翻译
15
15
  - **标准化结构**用于多语言文档
@@ -33,7 +33,7 @@ monoco i18n scan
33
33
 
34
34
  ## 配置
35
35
 
36
- I18n 设置在 `.monoco/config.yaml` 中配置:
36
+ I18n 设置在 `.monoco/config.yaml` 中配置:
37
37
 
38
38
  ```yaml
39
39
  i18n:
@@ -47,7 +47,7 @@ i18n:
47
47
 
48
48
  ### 根文件(后缀模式)
49
49
 
50
- 对于项目根目录中的文件:
50
+ 对于项目根目录中的文件:
51
51
 
52
52
  - 源文件: `README.md`
53
53
  - 中文: `README_ZH.md`
@@ -55,7 +55,7 @@ i18n:
55
55
 
56
56
  ### 子目录文件(目录模式)
57
57
 
58
- 对于 `docs/` 或其他目录中的文件:
58
+ 对于 `docs/` 或其他目录中的文件:
59
59
 
60
60
  ```
61
61
  docs/
@@ -72,7 +72,7 @@ docs/
72
72
 
73
73
  ## 排除规则
74
74
 
75
- 以下内容会自动从 i18n 扫描中排除:
75
+ 以下内容会自动从 i18n 扫描中排除:
76
76
 
77
77
  - `.gitignore` 模式(自动遵循)
78
78
  - `.references/` 目录