monoco-toolkit 0.2.2__py3-none-any.whl → 0.2.4__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.
@@ -0,0 +1,246 @@
1
+ import re
2
+ import yaml
3
+ from typing import List, Set, Optional, Dict
4
+ from pathlib import Path
5
+
6
+ from monoco.core.lsp import Diagnostic, DiagnosticSeverity, Range, Position
7
+ from .models import IssueMetadata, IssueStatus, IssueStage, IssueType
8
+
9
+ class IssueValidator:
10
+ """
11
+ Centralized validation logic for Issue Tickets.
12
+ Returns LSP-compatible Diagnostics.
13
+ """
14
+
15
+ def __init__(self, issue_root: Optional[Path] = None):
16
+ self.issue_root = issue_root
17
+
18
+ def validate(self, meta: IssueMetadata, content: str, all_issue_ids: Set[str] = set()) -> List[Diagnostic]:
19
+ diagnostics = []
20
+
21
+ # 1. State Matrix Validation
22
+ diagnostics.extend(self._validate_state_matrix(meta, content))
23
+
24
+ # 2. Content Completeness (Checkbox check)
25
+ diagnostics.extend(self._validate_content_completeness(meta, content))
26
+
27
+ # 3. Structure Consistency (Headings)
28
+ diagnostics.extend(self._validate_structure(meta, content))
29
+
30
+ # 4. Lifecycle/Integrity (Solution, etc.)
31
+ diagnostics.extend(self._validate_integrity(meta, content))
32
+
33
+ # 5. Reference Integrity
34
+ diagnostics.extend(self._validate_references(meta, content, all_issue_ids))
35
+
36
+ # 6. Time Consistency
37
+ diagnostics.extend(self._validate_time_consistency(meta, content))
38
+
39
+ # 7. Checkbox Syntax
40
+ diagnostics.extend(self._validate_checkbox_logic(content))
41
+
42
+ return diagnostics
43
+
44
+ def _create_diagnostic(self, message: str, severity: DiagnosticSeverity, line: int = 0) -> Diagnostic:
45
+ """Helper to create a diagnostic object."""
46
+ return Diagnostic(
47
+ range=Range(
48
+ start=Position(line=line, character=0),
49
+ end=Position(line=line, character=100) # Arbitrary end
50
+ ),
51
+ severity=severity,
52
+ message=message
53
+ )
54
+
55
+ def _get_field_line(self, content: str, field_name: str) -> int:
56
+ """Helper to find the line number of a field in the front matter."""
57
+ lines = content.split('\n')
58
+ in_fm = False
59
+ for i, line in enumerate(lines):
60
+ stripped = line.strip()
61
+ if stripped == "---":
62
+ if not in_fm:
63
+ in_fm = True
64
+ continue
65
+ else:
66
+ break # End of FM
67
+ if in_fm:
68
+ # Match "field:", "field :", or "field: value"
69
+ if re.match(rf"^{re.escape(field_name)}\s*:", stripped):
70
+ return i
71
+ return 0
72
+
73
+ def _validate_state_matrix(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
74
+ diagnostics = []
75
+
76
+ # Check based on parsed metadata (now that auto-correction is disabled)
77
+ if meta.status == IssueStatus.CLOSED and meta.stage != IssueStage.DONE:
78
+ line = self._get_field_line(content, "status")
79
+ diagnostics.append(self._create_diagnostic(
80
+ f"State Mismatch: Closed issues must be in 'Done' stage (found: {meta.stage.value if meta.stage else 'None'})",
81
+ DiagnosticSeverity.Error,
82
+ line=line
83
+ ))
84
+
85
+ if meta.status == IssueStatus.BACKLOG and meta.stage != IssueStage.FREEZED:
86
+ line = self._get_field_line(content, "status")
87
+ diagnostics.append(self._create_diagnostic(
88
+ f"State Mismatch: Backlog issues must be in 'Freezed' stage (found: {meta.stage.value if meta.stage else 'None'})",
89
+ DiagnosticSeverity.Error,
90
+ line=line
91
+ ))
92
+
93
+ return diagnostics
94
+
95
+ def _validate_content_completeness(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
96
+ diagnostics = []
97
+ # Checkbox regex: - [ ] or - [x] or - [-] or - [/]
98
+ checkboxes = re.findall(r"-\s*\[([ x\-/])\]", content)
99
+
100
+ if len(checkboxes) < 2:
101
+ diagnostics.append(self._create_diagnostic(
102
+ "Content Incomplete: Ticket must contain at least 2 checkboxes (AC & Tasks).",
103
+ DiagnosticSeverity.Warning
104
+ ))
105
+
106
+ if meta.stage in [IssueStage.REVIEW, IssueStage.DONE]:
107
+ # No empty checkboxes allowed
108
+ if ' ' in checkboxes:
109
+ # Find the first occurrence line
110
+ lines = content.split('\n')
111
+ first_line = 0
112
+ for i, line in enumerate(lines):
113
+ if re.search(r"-\s*\[ \]", line):
114
+ first_line = i
115
+ break
116
+
117
+ diagnostics.append(self._create_diagnostic(
118
+ f"Incomplete Tasks: Issue in {meta.stage} cannot have unchecked boxes.",
119
+ DiagnosticSeverity.Error,
120
+ line=first_line
121
+ ))
122
+ return diagnostics
123
+
124
+ def _validate_structure(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
125
+ diagnostics = []
126
+ lines = content.split('\n')
127
+
128
+ # 1. Heading check: ## {issue-id}: {issue-title}
129
+ expected_header = f"## {meta.id}: {meta.title}"
130
+ header_found = False
131
+
132
+ # 2. Review Comments Check
133
+ review_header_found = False
134
+ review_content_found = False
135
+
136
+ for i, line in enumerate(lines):
137
+ line_stripped = line.strip()
138
+ if line_stripped == expected_header:
139
+ header_found = True
140
+
141
+ if line_stripped == "## Review Comments":
142
+ review_header_found = True
143
+ # Check near lines for content
144
+ # This is a naive check (next line is not empty)
145
+ if i + 1 < len(lines) and lines[i+1].strip():
146
+ review_content_found = True
147
+ elif i + 2 < len(lines) and lines[i+2].strip():
148
+ review_content_found = True
149
+
150
+ if not header_found:
151
+ diagnostics.append(self._create_diagnostic(
152
+ f"Structure Error: Missing Level 2 Heading '{expected_header}'",
153
+ DiagnosticSeverity.Warning
154
+ ))
155
+
156
+ if meta.stage in [IssueStage.REVIEW, IssueStage.DONE]:
157
+ if not review_header_found:
158
+ diagnostics.append(self._create_diagnostic(
159
+ "Review Requirement: Missing '## Review Comments' section.",
160
+ DiagnosticSeverity.Error
161
+ ))
162
+ elif not review_content_found:
163
+ diagnostics.append(self._create_diagnostic(
164
+ "Review Requirement: '## Review Comments' section is empty.",
165
+ DiagnosticSeverity.Error
166
+ ))
167
+ return diagnostics
168
+
169
+ def _validate_integrity(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
170
+ diagnostics = []
171
+ if meta.status == IssueStatus.CLOSED and not meta.solution:
172
+ line = self._get_field_line(content, "status")
173
+ diagnostics.append(self._create_diagnostic(
174
+ f"Data Integrity: Closed issue {meta.id} missing 'solution' field.",
175
+ DiagnosticSeverity.Error,
176
+ line=line
177
+ ))
178
+ return diagnostics
179
+
180
+ def _validate_references(self, meta: IssueMetadata, content: str, all_ids: Set[str]) -> List[Diagnostic]:
181
+ diagnostics = []
182
+ if not all_ids:
183
+ return diagnostics
184
+
185
+ if meta.parent and meta.parent not in all_ids:
186
+ line = self._get_field_line(content, "parent")
187
+ diagnostics.append(self._create_diagnostic(
188
+ f"Broken Reference: Parent '{meta.parent}' not found.",
189
+ DiagnosticSeverity.Error,
190
+ line=line
191
+ ))
192
+
193
+ for dep in meta.dependencies:
194
+ if dep not in all_ids:
195
+ line = self._get_field_line(content, "dependencies")
196
+ diagnostics.append(self._create_diagnostic(
197
+ f"Broken Reference: Dependency '{dep}' not found.",
198
+ DiagnosticSeverity.Error,
199
+ line=line
200
+ ))
201
+ return diagnostics
202
+
203
+ def _validate_time_consistency(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
204
+ diagnostics = []
205
+ c = meta.created_at
206
+ o = meta.opened_at
207
+ u = meta.updated_at
208
+ cl = meta.closed_at
209
+
210
+ created_line = self._get_field_line(content, "created_at")
211
+ opened_line = self._get_field_line(content, "opened_at")
212
+ updated_line = self._get_field_line(content, "updated_at")
213
+ closed_line = self._get_field_line(content, "closed_at")
214
+
215
+ if o and c > o:
216
+ diagnostics.append(self._create_diagnostic("Time Travel: created_at > opened_at", DiagnosticSeverity.Warning, line=created_line))
217
+
218
+ if u and c > u:
219
+ diagnostics.append(self._create_diagnostic("Time Travel: created_at > updated_at", DiagnosticSeverity.Warning, line=created_line))
220
+
221
+ if cl:
222
+ if c > cl:
223
+ diagnostics.append(self._create_diagnostic("Time Travel: created_at > closed_at", DiagnosticSeverity.Error, line=created_line))
224
+ if o and o > cl:
225
+ diagnostics.append(self._create_diagnostic("Time Travel: opened_at > closed_at", DiagnosticSeverity.Error, line=opened_line))
226
+
227
+ return diagnostics
228
+
229
+ def _validate_checkbox_logic(self, content: str) -> List[Diagnostic]:
230
+ diagnostics = []
231
+ lines = content.split('\n')
232
+
233
+ for i, line in enumerate(lines):
234
+ stripped = line.lstrip()
235
+
236
+ # Syntax Check: - [?]
237
+ if stripped.startswith("- ["):
238
+ match = re.match(r"- \[([ x\-/])\]", stripped)
239
+ if not match:
240
+ # Check for Common errors
241
+ if re.match(r"- \[.{2,}\]", stripped): # [xx] or [ ]
242
+ diagnostics.append(self._create_diagnostic("Invalid Checkbox: Use single character [ ], [x], [-], [/]", DiagnosticSeverity.Error, i))
243
+ elif re.match(r"- \[([^ x\-/])\]", stripped): # [v], [o]
244
+ diagnostics.append(self._create_diagnostic("Invalid Checkbox Status: Use [ ], [x], [-], [/]", DiagnosticSeverity.Error, i))
245
+
246
+ return diagnostics
monoco/main.py CHANGED
@@ -13,11 +13,29 @@ app = typer.Typer(
13
13
 
14
14
  def version_callback(value: bool):
15
15
  if value:
16
- import importlib.metadata
16
+ # Try to read from pyproject.toml first (for dev mode)
17
+ from pathlib import Path
18
+
19
+ version = "unknown"
20
+
17
21
  try:
18
- version = importlib.metadata.version("monoco-toolkit")
19
- except importlib.metadata.PackageNotFoundError:
20
- version = "unknown"
22
+ # Look for pyproject.toml relative to this file
23
+ # monoco/main.py -> ../pyproject.toml
24
+ pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
25
+ if pyproject_path.exists():
26
+ with open(pyproject_path, "r", encoding="utf-8") as f:
27
+ for line in f:
28
+ if line.strip().startswith('version = "'):
29
+ version = line.split('"')[1]
30
+ break
31
+
32
+ if version == "unknown":
33
+ import importlib.metadata
34
+ version = importlib.metadata.version("monoco-toolkit")
35
+ except Exception:
36
+ # Fallback
37
+ pass
38
+
21
39
  print(f"Monoco Toolkit v{version}")
22
40
  raise typer.Exit()
23
41
 
@@ -28,6 +46,9 @@ def main(
28
46
  version: Optional[bool] = typer.Option(
29
47
  None, "--version", "-v", help="Show version and exit", callback=version_callback, is_eager=True
30
48
  ),
49
+ root: Optional[str] = typer.Option(
50
+ None, "--root", help="Explicitly specify the Monoco Workspace root directory."
51
+ )
31
52
  ):
32
53
  """
33
54
  Monoco Toolkit - The sensory and motor system for Monoco Agents.
@@ -37,6 +58,31 @@ def main(
37
58
  if ctx.invoked_subcommand:
38
59
  capture_event("cli_command_executed", {"command": ctx.invoked_subcommand})
39
60
 
61
+ # Strict Workspace Resolution
62
+ # Commands allowed to run without a workspace
63
+ NO_WORKSPACE_COMMANDS = ["init", "clone"]
64
+
65
+ # Initialize Config
66
+ from monoco.core.config import get_config
67
+ from pathlib import Path
68
+
69
+ # If subcommand is not in whitelist, we enforce workspace
70
+ require_workspace = False
71
+ if ctx.invoked_subcommand and ctx.invoked_subcommand not in NO_WORKSPACE_COMMANDS:
72
+ require_workspace = True
73
+
74
+ try:
75
+ # We pass root if provided. If require_workspace is True, get_config will throw if not found.
76
+ # Note: If root is None, it defaults to CWD in get_config.
77
+ get_config(project_root=root, require_project=require_workspace)
78
+ except FileNotFoundError as e:
79
+ # Graceful exit for workspace errors
80
+ from rich.console import Console
81
+ console = Console()
82
+ console.print(f"[bold red]Error:[/bold red] {e}")
83
+ console.print(f"[yellow]Tip:[/yellow] Run this command in a Monoco Workspace root (containing .monoco), or use [bold]--root <path>[/bold].")
84
+ raise typer.Exit(code=1)
85
+
40
86
  from monoco.core.setup import init_cli
41
87
  app.command(name="init")(init_cli)
42
88
 
@@ -96,11 +142,15 @@ from monoco.features.issue import commands as issue_cmd
96
142
  from monoco.features.spike import commands as spike_cmd
97
143
  from monoco.features.i18n import commands as i18n_cmd
98
144
  from monoco.features.config import commands as config_cmd
145
+ from monoco.cli import project as project_cmd
146
+ from monoco.cli import workspace as workspace_cmd
99
147
 
100
148
  app.add_typer(issue_cmd.app, name="issue", help="Manage development issues")
101
149
  app.add_typer(spike_cmd.app, name="spike", help="Manage research spikes")
102
150
  app.add_typer(i18n_cmd.app, name="i18n", help="Manage documentation i18n")
103
151
  app.add_typer(config_cmd.app, name="config", help="Manage configuration")
152
+ app.add_typer(project_cmd.app, name="project", help="Manage projects")
153
+ app.add_typer(workspace_cmd.app, name="workspace", help="Manage workspace")
104
154
 
105
155
  from monoco.features.agent import commands as agent_cmd
106
156
  app.add_typer(agent_cmd.app, name="agent", help="Delegate tasks to Agent CLIs")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: monoco-toolkit
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Agent Native Toolkit for Monoco - Task Management & Kanban for AI Agents
5
5
  Project-URL: Homepage, https://monoco.io
6
6
  Project-URL: Repository, https://github.com/IndenScale/Monoco
@@ -1,24 +1,28 @@
1
- monoco/main.py,sha256=ZQXcATWam1Uveo_StkWZ2jJH7qkQ23ZBNy7cvEgtsoQ,3603
1
+ monoco/main.py,sha256=obHguPiyKiVLQLKvIE3k8AlSWTBYXWL884b1HkKJVXs,5745
2
+ monoco/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ monoco/cli/project.py,sha256=5zEbKDM5PJAHc8XCOjuJkOlJUkj3Lm61bSXDg4iIBUg,2631
4
+ monoco/cli/workspace.py,sha256=R8ru4wUQxGG2PLjzpPxf4UF5GBWYMHEA0CTDyIeO3II,1122
2
5
  monoco/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- monoco/core/config.py,sha256=5JUThWPMQZav-6Pws9LKfLwULuowDvu-yk-lBTm0FA0,8606
6
+ monoco/core/config.py,sha256=DCfUa33BA-moTiEzWqVf7rBaTIW9_gUAjNXHZW05_Ho,10221
4
7
  monoco/core/execution.py,sha256=rySL0ueJvTEQ1JhdpumsNBQHJpj08nfaHQMlX-1uh6k,1846
5
8
  monoco/core/feature.py,sha256=oAtQWUHMuqIFbq2gj8sPfYBlJZvMMXZqyUlCMrIVGUE,2007
6
9
  monoco/core/git.py,sha256=i_NKT9_n57S9EKeb8kF2yTEdw70FZ88-lpMqW4lzVds,8228
7
10
  monoco/core/injection.py,sha256=4BuQ5RVozyU99uSOzPwgc6MFMZUcECerTik5lF39I9A,7078
8
- monoco/core/integrations.py,sha256=rDgSFBzBMmXX1BhlcMoFd8gBS_ziiNzkvayKi6mjocA,5659
11
+ monoco/core/integrations.py,sha256=QRZjCwHb6xudIoxrFSE_gvQKNWlIOXGn-SxZelqqrWw,7667
12
+ monoco/core/lsp.py,sha256=aif3iMgfpyCrBL1qlbakJerjT--ePwoWnRa-5CCMMkY,1844
9
13
  monoco/core/output.py,sha256=9JbCxqxHZlviNJXpUorGVxv_gAn4q72FPgjwBQrPiCI,3502
10
14
  monoco/core/registry.py,sha256=xix21TDeJgRiZ2kvHitnac4RsqMdp1aERpYGSrwfIpY,1180
11
- monoco/core/setup.py,sha256=MXeSKxz62Rh47E_BqLI0t_R7MkcsVeHvar5Tcz9ig4w,9335
15
+ monoco/core/setup.py,sha256=nahBMz80DyDZDd-p4IorJtdtH4gagW6FPwJQd8b1Ogc,9395
12
16
  monoco/core/skills.py,sha256=5qK-0YlOnNQLqyo6-T4GVBrkjsbrszb5ugXeXRRcQ00,16597
13
17
  monoco/core/state.py,sha256=KlmOn0KXO8g9S_KUIrUylAKdBpyH_1AOBvrYSj_khdE,1884
14
18
  monoco/core/sync.py,sha256=s0qQ5PsVn_IWGWUNThdvNFS-CncztDzsTM3QLupC6Og,8514
15
19
  monoco/core/telemetry.py,sha256=DZQGOhvpe0XL34RCDaTZEUhmkD4abBTZumZJQlALzpY,2923
16
- monoco/core/workspace.py,sha256=PaCciUzUjIBkTXpF0CEx0hTQfForEPL2H0sYJP54b98,2839
20
+ monoco/core/workspace.py,sha256=0RWx8H_Kx56TYVrAURTSJW4aWOUylXofkvXBhRNjP_E,3074
17
21
  monoco/core/agent/__init__.py,sha256=tBCm6PDqPFo81yO949nW897INjl7ot46CPup9IrXExE,108
18
22
  monoco/core/agent/action.py,sha256=HpOLzp-mttJY0SDVbRlstDVqjFKozIAdjQdJ4Gp3xiY,5161
19
23
  monoco/core/agent/adapters.py,sha256=3M6-8uz_WOxXY1bMdu3epQ15v9dc-8Bolq00-mwLxwM,3517
20
24
  monoco/core/agent/protocol.py,sha256=E7y_i2JzYGpzSCRCUIuzu1ATav-Xu1K01ka6Zncm4-o,831
21
- monoco/core/agent/state.py,sha256=M-VgwSMNbIkr1JNB1U6N4qBE5BV4hjQf_C9_Woms-lA,4057
25
+ monoco/core/agent/state.py,sha256=sRav6uwkXao8yPl08CEB-cqK1EfiDyMnVxoSYxvYcis,3523
22
26
  monoco/core/resources/en/AGENTS.md,sha256=3TpCLNC1s_lIbDfJJBRmmROMoy9sZXu8BOag8M9NXI0,327
23
27
  monoco/core/resources/en/SKILL.md,sha256=_1leQQDZ4CoSkWzTd5UmCYpDgSOeQc51uuo1-DGhTlM,2169
24
28
  monoco/core/resources/zh/AGENTS.md,sha256=pGQOLt8mcRygJotd5oC8l9604hikQoUiS99QsHCe-UM,298
@@ -43,17 +47,18 @@ monoco/features/i18n/resources/en/SKILL.md,sha256=Z8fAAqeMvpLDw1D_9AzZIykS5-HLVM
43
47
  monoco/features/i18n/resources/zh/AGENTS.md,sha256=lKkwLLCADRH7UDq9no4eQY2sRfJrb64JoZ_HNved8vA,175
44
48
  monoco/features/i18n/resources/zh/SKILL.md,sha256=y2UuwhZmCBy0pXGxWLNrhxb94zcNfGEMBA_imJgDqVg,1894
45
49
  monoco/features/issue/adapter.py,sha256=Y-ghwRoSEgm_A-cqY8Un-5srxydXdb9ytlKHLm89eJQ,1265
46
- monoco/features/issue/commands.py,sha256=tDp4LgCWMFvzJttr6BUQOW7APhUDEPRC2YRx6aO8zdI,29446
47
- monoco/features/issue/core.py,sha256=whvUONF4Fak3xU6YBg-Ywg2OVlyaToP30Pb25Bly33w,44702
48
- monoco/features/issue/linter.py,sha256=ZMNpp_0ehbzBMYROfPtCr4O4JL8mhdO9L0F3EAi96lE,7657
50
+ monoco/features/issue/commands.py,sha256=spXU4Xv9zs2kNWHnNf1PB5yVhvtUQgFWv3e-1vMKI9M,31752
51
+ monoco/features/issue/core.py,sha256=cAPmJVLMCPMkfMe2WNZVdSQr0Pg6s8sN-SMU7LlhtR0,47108
52
+ monoco/features/issue/linter.py,sha256=g98_NKXZFGw0ewBX7g-80CAKvPE0zdazQw1hT2uFtcU,11117
49
53
  monoco/features/issue/migration.py,sha256=9gtgFi1V1pzwXo0-H4cIoBvSBERIWopXLCB4oSxTQLc,4715
50
- monoco/features/issue/models.py,sha256=mSepSUX4kM4IEc60yyRWmB37VWWuGD8ZQA4hDyxILJM,5434
54
+ monoco/features/issue/models.py,sha256=pMBLvcGrqO0tpf-7TMnt9VAIzgkq5P79-hqfH8T_EBw,5044
51
55
  monoco/features/issue/monitor.py,sha256=QEN0mqZ3tKwBfMjN87-LdrVoIEe0prA-uMHOBGy1VZk,3476
56
+ monoco/features/issue/validator.py,sha256=e-OXkWrMIHkXbjvEd9qLSHLfjp9A8SXHRSF2_WOvOGg,10405
52
57
  monoco/features/issue/executions/refine.md,sha256=SMTxPB3W-oH3FPoRDdRTYmg2l1Jpez3UhZNcj0GMIrQ,867
53
- monoco/features/issue/resources/en/AGENTS.md,sha256=N25fg10hiUgBIFmb1P2a6H1qzMsnLEmdYrvdqnYqh6E,451
54
- monoco/features/issue/resources/en/SKILL.md,sha256=pGIgqgMnIpMIB0NwfSm2aJCuhpdk8fe8Q4wAm5kLG3M,1394
55
- monoco/features/issue/resources/zh/AGENTS.md,sha256=2aK2QTsKZqYxpE2fg9yFK_ORrhONo8t9ueebUN2k-KQ,461
56
- monoco/features/issue/resources/zh/SKILL.md,sha256=2sflhl1PAUW5Q7wGH-d80OcQ_CDTPD-Hucsx6YKdE6Y,2570
58
+ monoco/features/issue/resources/en/AGENTS.md,sha256=OjEnkXCqwfMArJfJQhldrQYXqoregfGthyhJeyx7MPw,715
59
+ monoco/features/issue/resources/en/SKILL.md,sha256=p0vhVpe3xLKg0iXSNofoLNvsq8j2pmv5CD1B2mUeIGk,2732
60
+ monoco/features/issue/resources/zh/AGENTS.md,sha256=2MLIZ5-i-oBnl7_YAZBBoKkNqANpHj73iw18QQbSm5c,759
61
+ monoco/features/issue/resources/zh/SKILL.md,sha256=_aXDThhsJag9OLK2X5LRVhaFyMcl4DcZvcSj1_UUkx8,3828
57
62
  monoco/features/pty/core.py,sha256=eM1EvHQrgExSnatO15pyfhh1VZoz0BBTfNYdXqG8HZ8,5711
58
63
  monoco/features/pty/router.py,sha256=7h80EPpOuE7hX5ifkxkzffcLZGecd5X8OmNvOji5ToI,5078
59
64
  monoco/features/pty/server.py,sha256=kw2csMZ_R4_Xx6ta2dbznWtgNZLfrWOAkMp8NjlZYBc,1920
@@ -66,8 +71,8 @@ monoco/features/spike/resources/en/AGENTS.md,sha256=NG3CMnlDk_0J8hnRUcueAM9lgIQr
66
71
  monoco/features/spike/resources/en/SKILL.md,sha256=qKDcVh0D3pDRvfNLh1Bzo4oQU3obpl4tqdlzxeiWYMk,1911
67
72
  monoco/features/spike/resources/zh/AGENTS.md,sha256=5RHNl7fc3RdYYTFH483ojJl_arGPKkyYziOuGgFbqqg,290
68
73
  monoco/features/spike/resources/zh/SKILL.md,sha256=boGPgAfTHbEzdwomRh-qVEveWSgvYaPUdi_4YZVXGHI,1714
69
- monoco_toolkit-0.2.2.dist-info/METADATA,sha256=eoszTd4STcuf0cgsguYN9a6D-SoTgajZ3dPTOOtX1k0,3743
70
- monoco_toolkit-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
71
- monoco_toolkit-0.2.2.dist-info/entry_points.txt,sha256=iYj7FWYBdtClU15-Du1skqD0s6SFSIhJvxJ29VWp8ng,43
72
- monoco_toolkit-0.2.2.dist-info/licenses/LICENSE,sha256=ACAGGjV6aod4eIlVUTx1q9PZbnZGN5bBwkSs9RHj83s,1071
73
- monoco_toolkit-0.2.2.dist-info/RECORD,,
74
+ monoco_toolkit-0.2.4.dist-info/METADATA,sha256=5LPrW0Ld_4-NCkVLIIVDTOlCvgpcXorrO5Eb30QPnZY,3743
75
+ monoco_toolkit-0.2.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
76
+ monoco_toolkit-0.2.4.dist-info/entry_points.txt,sha256=iYj7FWYBdtClU15-Du1skqD0s6SFSIhJvxJ29VWp8ng,43
77
+ monoco_toolkit-0.2.4.dist-info/licenses/LICENSE,sha256=ACAGGjV6aod4eIlVUTx1q9PZbnZGN5bBwkSs9RHj83s,1071
78
+ monoco_toolkit-0.2.4.dist-info/RECORD,,