monoco-toolkit 0.2.5__py3-none-any.whl → 0.2.6__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.
- monoco/core/agent/adapters.py +24 -1
- monoco/core/config.py +63 -1
- monoco/core/integrations.py +8 -0
- monoco/core/lsp.py +7 -0
- monoco/core/output.py +8 -1
- monoco/core/setup.py +8 -0
- monoco/features/agent/commands.py +73 -2
- monoco/features/agent/core.py +48 -0
- monoco/features/agent/resources/en/critique.prompty +16 -0
- monoco/features/agent/resources/en/develop.prompty +16 -0
- monoco/features/agent/resources/en/investigate.prompty +16 -0
- monoco/features/agent/resources/en/refine.prompty +14 -0
- monoco/features/agent/resources/en/verify.prompty +16 -0
- monoco/features/agent/resources/zh/critique.prompty +18 -0
- monoco/features/agent/resources/zh/develop.prompty +18 -0
- monoco/features/agent/resources/zh/investigate.prompty +18 -0
- monoco/features/agent/resources/zh/refine.prompty +16 -0
- monoco/features/agent/resources/zh/verify.prompty +18 -0
- monoco/features/issue/commands.py +133 -35
- monoco/features/issue/core.py +142 -119
- monoco/features/issue/domain/__init__.py +0 -0
- monoco/features/issue/domain/lifecycle.py +126 -0
- monoco/features/issue/domain/models.py +170 -0
- monoco/features/issue/domain/parser.py +223 -0
- monoco/features/issue/domain/workspace.py +104 -0
- monoco/features/issue/engine/__init__.py +22 -0
- monoco/features/issue/engine/config.py +189 -0
- monoco/features/issue/engine/machine.py +185 -0
- monoco/features/issue/engine/models.py +18 -0
- monoco/features/issue/linter.py +32 -11
- monoco/features/issue/lsp/__init__.py +3 -0
- monoco/features/issue/lsp/definition.py +72 -0
- monoco/features/issue/models.py +8 -8
- monoco/features/issue/validator.py +181 -65
- monoco/features/spike/core.py +5 -22
- monoco/main.py +0 -15
- {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.6.dist-info}/METADATA +1 -1
- {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.6.dist-info}/RECORD +41 -22
- monoco/features/pty/core.py +0 -185
- monoco/features/pty/router.py +0 -138
- monoco/features/pty/server.py +0 -56
- {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.6.dist-info}/WHEEL +0 -0
- {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.6.dist-info}/entry_points.txt +0 -0
- {monoco_toolkit-0.2.5.dist-info → monoco_toolkit-0.2.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,7 +6,9 @@ from pathlib import Path
|
|
|
6
6
|
from monoco.core.lsp import Diagnostic, DiagnosticSeverity, Range, Position
|
|
7
7
|
from monoco.core.config import get_config
|
|
8
8
|
from monoco.features.i18n.core import detect_language
|
|
9
|
-
from .models import IssueMetadata,
|
|
9
|
+
from .models import IssueMetadata, IssueType
|
|
10
|
+
from .domain.parser import MarkdownParser
|
|
11
|
+
from .domain.models import ContentBlock
|
|
10
12
|
|
|
11
13
|
class IssueValidator:
|
|
12
14
|
"""
|
|
@@ -20,14 +22,41 @@ class IssueValidator:
|
|
|
20
22
|
def validate(self, meta: IssueMetadata, content: str, all_issue_ids: Set[str] = set()) -> List[Diagnostic]:
|
|
21
23
|
diagnostics = []
|
|
22
24
|
|
|
25
|
+
# Parse Content into Blocks (Domain Layer)
|
|
26
|
+
# Handle case where content might be just body (from update_issue) or full file
|
|
27
|
+
if content.startswith("---"):
|
|
28
|
+
try:
|
|
29
|
+
issue_domain = MarkdownParser.parse(content)
|
|
30
|
+
blocks = issue_domain.body.blocks
|
|
31
|
+
has_frontmatter = True
|
|
32
|
+
except Exception:
|
|
33
|
+
# Fallback if parser fails (e.g. invalid YAML)
|
|
34
|
+
# We continue with empty blocks or try partial parsing?
|
|
35
|
+
# For now, let's try to parse blocks ignoring FM
|
|
36
|
+
lines = content.splitlines()
|
|
37
|
+
# Find end of FM
|
|
38
|
+
start_line = 0
|
|
39
|
+
if lines[0].strip() == "---":
|
|
40
|
+
for i in range(1, len(lines)):
|
|
41
|
+
if lines[i].strip() == "---":
|
|
42
|
+
start_line = i + 1
|
|
43
|
+
break
|
|
44
|
+
blocks = MarkdownParser._parse_blocks(lines[start_line:], start_line_offset=start_line)
|
|
45
|
+
has_frontmatter = True
|
|
46
|
+
else:
|
|
47
|
+
# Assume content is just body
|
|
48
|
+
lines = content.splitlines()
|
|
49
|
+
blocks = MarkdownParser._parse_blocks(lines, start_line_offset=0)
|
|
50
|
+
has_frontmatter = False
|
|
51
|
+
|
|
23
52
|
# 1. State Matrix Validation
|
|
24
53
|
diagnostics.extend(self._validate_state_matrix(meta, content))
|
|
25
54
|
|
|
26
|
-
# 2.
|
|
27
|
-
diagnostics.extend(self.
|
|
55
|
+
# 2. State Requirements (Strict Verification)
|
|
56
|
+
diagnostics.extend(self._validate_state_requirements(meta, blocks))
|
|
28
57
|
|
|
29
|
-
# 3. Structure Consistency (Headings)
|
|
30
|
-
diagnostics.extend(self.
|
|
58
|
+
# 3. Structure Consistency (Headings) - Using Blocks
|
|
59
|
+
diagnostics.extend(self._validate_structure_blocks(meta, blocks))
|
|
31
60
|
|
|
32
61
|
# 4. Lifecycle/Integrity (Solution, etc.)
|
|
33
62
|
diagnostics.extend(self._validate_integrity(meta, content))
|
|
@@ -38,8 +67,8 @@ class IssueValidator:
|
|
|
38
67
|
# 6. Time Consistency
|
|
39
68
|
diagnostics.extend(self._validate_time_consistency(meta, content))
|
|
40
69
|
|
|
41
|
-
# 7. Checkbox Syntax
|
|
42
|
-
diagnostics.extend(self.
|
|
70
|
+
# 7. Checkbox Syntax - Using Blocks
|
|
71
|
+
diagnostics.extend(self._validate_checkbox_logic_blocks(blocks))
|
|
43
72
|
|
|
44
73
|
# 8. Language Consistency
|
|
45
74
|
diagnostics.extend(self._validate_language_consistency(meta, content))
|
|
@@ -97,56 +126,102 @@ class IssueValidator:
|
|
|
97
126
|
diagnostics = []
|
|
98
127
|
|
|
99
128
|
# Check based on parsed metadata (now that auto-correction is disabled)
|
|
100
|
-
if meta.status ==
|
|
129
|
+
if meta.status == "closed" and meta.stage != "done":
|
|
101
130
|
line = self._get_field_line(content, "status")
|
|
102
131
|
diagnostics.append(self._create_diagnostic(
|
|
103
|
-
f"State Mismatch: Closed issues must be in 'Done' stage (found: {meta.stage
|
|
132
|
+
f"State Mismatch: Closed issues must be in 'Done' stage (found: {meta.stage if meta.stage else 'None'})",
|
|
104
133
|
DiagnosticSeverity.Error,
|
|
105
134
|
line=line
|
|
106
135
|
))
|
|
107
136
|
|
|
108
|
-
if meta.status ==
|
|
137
|
+
if meta.status == "backlog" and meta.stage != "freezed":
|
|
109
138
|
line = self._get_field_line(content, "status")
|
|
110
139
|
diagnostics.append(self._create_diagnostic(
|
|
111
|
-
f"State Mismatch: Backlog issues must be in 'Freezed' stage (found: {meta.stage
|
|
140
|
+
f"State Mismatch: Backlog issues must be in 'Freezed' stage (found: {meta.stage if meta.stage else 'None'})",
|
|
112
141
|
DiagnosticSeverity.Error,
|
|
113
142
|
line=line
|
|
114
143
|
))
|
|
115
144
|
|
|
116
145
|
return diagnostics
|
|
117
146
|
|
|
118
|
-
def
|
|
147
|
+
def _validate_state_requirements(self, meta: IssueMetadata, blocks: List[ContentBlock]) -> List[Diagnostic]:
|
|
119
148
|
diagnostics = []
|
|
120
|
-
# Checkbox regex: - [ ] or - [x] or - [-] or - [/]
|
|
121
|
-
checkboxes = re.findall(r"-\s*\[([ x\-/])\]", content)
|
|
122
149
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
# 1. Map Blocks to Sections
|
|
151
|
+
sections = {"tasks": [], "ac": [], "review": []}
|
|
152
|
+
current_section = None
|
|
153
|
+
|
|
154
|
+
for block in blocks:
|
|
155
|
+
if block.type == "heading":
|
|
156
|
+
title = block.content.strip().lower()
|
|
157
|
+
if "technical tasks" in title:
|
|
158
|
+
current_section = "tasks"
|
|
159
|
+
elif "acceptance criteria" in title:
|
|
160
|
+
current_section = "ac"
|
|
161
|
+
elif "review comments" in title:
|
|
162
|
+
current_section = "review"
|
|
163
|
+
else:
|
|
164
|
+
current_section = None
|
|
165
|
+
elif block.type == "task_item":
|
|
166
|
+
if current_section and current_section in sections:
|
|
167
|
+
sections[current_section].append(block)
|
|
168
|
+
|
|
169
|
+
# 2. Logic: DOING -> Must have defined tasks
|
|
170
|
+
if meta.stage in ["doing", "review", "done"]:
|
|
171
|
+
if not sections["tasks"]:
|
|
172
|
+
# We can't strictly point to a line if section missing, but we can point to top/bottom
|
|
173
|
+
# Or just a general error.
|
|
174
|
+
diagnostics.append(self._create_diagnostic(
|
|
175
|
+
"State Requirement (DOING+): Must define 'Technical Tasks' (at least 1 checkbox).",
|
|
176
|
+
DiagnosticSeverity.Warning
|
|
177
|
+
))
|
|
178
|
+
|
|
179
|
+
# 3. Logic: REVIEW -> Tasks must be Completed ([x]) or Cancelled ([~], [+])
|
|
180
|
+
# No [ ] (ToDo) or [-]/[/] (Doing) allowed.
|
|
181
|
+
if meta.stage in ["review", "done"]:
|
|
182
|
+
for block in sections["tasks"]:
|
|
183
|
+
content = block.content.strip()
|
|
184
|
+
# Check for explicit illegal states
|
|
185
|
+
if re.search(r"-\s*\[\s+\]", content):
|
|
186
|
+
diagnostics.append(self._create_diagnostic(
|
|
187
|
+
f"State Requirement ({meta.stage.upper()}): Technical Tasks must be resolved. Found Todo [ ]: '{content}'",
|
|
188
|
+
DiagnosticSeverity.Error,
|
|
189
|
+
line=block.line_start
|
|
190
|
+
))
|
|
191
|
+
elif re.search(r"-\s*\[[-\/]]", content):
|
|
192
|
+
diagnostics.append(self._create_diagnostic(
|
|
193
|
+
f"State Requirement ({meta.stage.upper()}): Technical Tasks must be finished (not Doing). Found Doing [-]: '{content}'",
|
|
194
|
+
DiagnosticSeverity.Error,
|
|
195
|
+
line=block.line_start
|
|
196
|
+
))
|
|
197
|
+
|
|
198
|
+
# 4. Logic: DONE -> AC must be Verified ([x])
|
|
199
|
+
if meta.stage == "done":
|
|
200
|
+
for block in sections["ac"]:
|
|
201
|
+
content = block.content.strip()
|
|
202
|
+
if not re.search(r"-\s*\[[xX]\]", content):
|
|
203
|
+
diagnostics.append(self._create_diagnostic(
|
|
204
|
+
f"State Requirement (DONE): Acceptance Criteria must be passed ([x]). Found: '{content}'",
|
|
205
|
+
DiagnosticSeverity.Error,
|
|
206
|
+
line=block.line_start
|
|
207
|
+
))
|
|
208
|
+
|
|
209
|
+
# 5. Logic: DONE -> Review Checkboxes (if any) must be Resolved ([x] or [~])
|
|
210
|
+
for block in sections["review"]:
|
|
211
|
+
content = block.content.strip()
|
|
212
|
+
# Must be [x], [X], [~], [+]
|
|
213
|
+
# Therefore [ ], [-], [/] are invalid blocking states
|
|
214
|
+
if re.search(r"-\s*\[[\s\-\/]\]", content):
|
|
215
|
+
diagnostics.append(self._create_diagnostic(
|
|
216
|
+
f"State Requirement (DONE): Actionable Review Comments must be resolved ([x] or [~]). Found: '{content}'",
|
|
217
|
+
DiagnosticSeverity.Error,
|
|
218
|
+
line=block.line_start
|
|
219
|
+
))
|
|
220
|
+
|
|
145
221
|
return diagnostics
|
|
146
222
|
|
|
147
|
-
def
|
|
223
|
+
def _validate_structure_blocks(self, meta: IssueMetadata, blocks: List[ContentBlock]) -> List[Diagnostic]:
|
|
148
224
|
diagnostics = []
|
|
149
|
-
lines = content.split('\n')
|
|
150
225
|
|
|
151
226
|
# 1. Heading check: ## {issue-id}: {issue-title}
|
|
152
227
|
expected_header = f"## {meta.id}: {meta.title}"
|
|
@@ -156,19 +231,25 @@ class IssueValidator:
|
|
|
156
231
|
review_header_found = False
|
|
157
232
|
review_content_found = False
|
|
158
233
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
234
|
+
review_header_index = -1
|
|
235
|
+
|
|
236
|
+
for i, block in enumerate(blocks):
|
|
237
|
+
if block.type == 'heading':
|
|
238
|
+
stripped = block.content.strip()
|
|
239
|
+
if stripped == expected_header:
|
|
240
|
+
header_found = True
|
|
241
|
+
|
|
242
|
+
if stripped == "## Review Comments":
|
|
243
|
+
review_header_found = True
|
|
244
|
+
review_header_index = i
|
|
245
|
+
|
|
246
|
+
# Check content after review header
|
|
247
|
+
if review_header_found:
|
|
248
|
+
# Check if there are blocks after review_header_index that are NOT empty
|
|
249
|
+
for j in range(review_header_index + 1, len(blocks)):
|
|
250
|
+
if blocks[j].type != 'empty':
|
|
251
|
+
review_content_found = True
|
|
252
|
+
break
|
|
172
253
|
|
|
173
254
|
if not header_found:
|
|
174
255
|
diagnostics.append(self._create_diagnostic(
|
|
@@ -176,7 +257,7 @@ class IssueValidator:
|
|
|
176
257
|
DiagnosticSeverity.Warning
|
|
177
258
|
))
|
|
178
259
|
|
|
179
|
-
if meta.stage in [
|
|
260
|
+
if meta.stage in ["review", "done"]:
|
|
180
261
|
if not review_header_found:
|
|
181
262
|
diagnostics.append(self._create_diagnostic(
|
|
182
263
|
"Review Requirement: Missing '## Review Comments' section.",
|
|
@@ -191,7 +272,7 @@ class IssueValidator:
|
|
|
191
272
|
|
|
192
273
|
def _validate_integrity(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
|
|
193
274
|
diagnostics = []
|
|
194
|
-
if meta.status ==
|
|
275
|
+
if meta.status == "closed" and not meta.solution:
|
|
195
276
|
line = self._get_field_line(content, "status")
|
|
196
277
|
diagnostics.append(self._create_diagnostic(
|
|
197
278
|
f"Data Integrity: Closed issue {meta.id} missing 'solution' field.",
|
|
@@ -221,6 +302,42 @@ class IssueValidator:
|
|
|
221
302
|
DiagnosticSeverity.Error,
|
|
222
303
|
line=line
|
|
223
304
|
))
|
|
305
|
+
|
|
306
|
+
# Body Reference Check
|
|
307
|
+
# Regex for generic issue ID: (EPIC|FEAT|CHORE|FIX)-\d{4}
|
|
308
|
+
# We scan line by line to get line numbers
|
|
309
|
+
lines = content.split('\n')
|
|
310
|
+
# Skip frontmatter for body check to avoid double counting (handled above)
|
|
311
|
+
in_fm = False
|
|
312
|
+
fm_end = 0
|
|
313
|
+
for i, line in enumerate(lines):
|
|
314
|
+
if line.strip() == '---':
|
|
315
|
+
if not in_fm: in_fm = True
|
|
316
|
+
else:
|
|
317
|
+
fm_end = i
|
|
318
|
+
break
|
|
319
|
+
|
|
320
|
+
for i, line in enumerate(lines):
|
|
321
|
+
if i <= fm_end: continue # Skip frontmatter
|
|
322
|
+
|
|
323
|
+
# Find all matches
|
|
324
|
+
matches = re.finditer(r"\b((?:EPIC|FEAT|CHORE|FIX)-\d{4})\b", line)
|
|
325
|
+
for match in matches:
|
|
326
|
+
ref_id = match.group(1)
|
|
327
|
+
if ref_id != meta.id and ref_id not in all_ids:
|
|
328
|
+
# Check if it's a namespaced ID? The regex only catches local IDs.
|
|
329
|
+
# If users use MON::FEAT-0001, the regex might catch FEAT-0001.
|
|
330
|
+
# But all_ids contains full IDs (potentially namespaced).
|
|
331
|
+
# Simple logic: if ref_id isn't in all_ids, check if any id ENDS with ref_id
|
|
332
|
+
|
|
333
|
+
found_namespaced = any(known.endswith(f"::{ref_id}") for known in all_ids)
|
|
334
|
+
|
|
335
|
+
if not found_namespaced:
|
|
336
|
+
diagnostics.append(self._create_diagnostic(
|
|
337
|
+
f"Broken Reference: Issue '{ref_id}' not found.",
|
|
338
|
+
DiagnosticSeverity.Warning,
|
|
339
|
+
line=i
|
|
340
|
+
))
|
|
224
341
|
return diagnostics
|
|
225
342
|
|
|
226
343
|
def _validate_time_consistency(self, meta: IssueMetadata, content: str) -> List[Diagnostic]:
|
|
@@ -249,21 +366,20 @@ class IssueValidator:
|
|
|
249
366
|
|
|
250
367
|
return diagnostics
|
|
251
368
|
|
|
252
|
-
def
|
|
369
|
+
def _validate_checkbox_logic_blocks(self, blocks: List[ContentBlock]) -> List[Diagnostic]:
|
|
253
370
|
diagnostics = []
|
|
254
|
-
lines = content.split('\n')
|
|
255
371
|
|
|
256
|
-
for
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
match = re.match(r"- \[([ x
|
|
372
|
+
for block in blocks:
|
|
373
|
+
if block.type == 'task_item':
|
|
374
|
+
content = block.content.strip()
|
|
375
|
+
# Syntax Check: - [?]
|
|
376
|
+
# Added supported chars: /, ~, +
|
|
377
|
+
match = re.match(r"- \[([ x\-/~+])\]", content)
|
|
262
378
|
if not match:
|
|
263
379
|
# Check for Common errors
|
|
264
|
-
if re.match(r"- \[.{2,}\]",
|
|
265
|
-
diagnostics.append(self._create_diagnostic("Invalid Checkbox: Use single character [ ], [x], [-], [/]", DiagnosticSeverity.Error,
|
|
266
|
-
elif re.match(r"- \[([^ x
|
|
267
|
-
diagnostics.append(self._create_diagnostic("Invalid Checkbox Status: Use [ ], [x], [
|
|
380
|
+
if re.match(r"- \[.{2,}\]", content): # [xx] or [ ]
|
|
381
|
+
diagnostics.append(self._create_diagnostic("Invalid Checkbox: Use single character [ ], [x], [-], [/]", DiagnosticSeverity.Error, block.line_start))
|
|
382
|
+
elif re.match(r"- \[([^ x\-/~+])\]", content): # [v], [o]
|
|
383
|
+
diagnostics.append(self._create_diagnostic("Invalid Checkbox Status: Use [ ], [x], [/], [~]", DiagnosticSeverity.Error, block.line_start))
|
|
268
384
|
|
|
269
385
|
return diagnostics
|
monoco/features/spike/core.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import shutil
|
|
3
3
|
import subprocess
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Dict, Optional, List, Any
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
|
|
9
|
-
from monoco.core.config import get_config
|
|
9
|
+
from monoco.core.config import get_config, load_raw_config, save_raw_config, ConfigScope
|
|
10
10
|
|
|
11
11
|
console = Console()
|
|
12
12
|
|
|
@@ -29,26 +29,10 @@ def run_git_command(cmd: List[str], cwd: Path) -> bool:
|
|
|
29
29
|
console.print("[red]Error:[/red] git command not found.")
|
|
30
30
|
return False
|
|
31
31
|
|
|
32
|
-
def get_config_file_path(root: Path) -> Path:
|
|
33
|
-
"""Determine the config file to update."""
|
|
34
|
-
# Standard: .monoco/project.yaml
|
|
35
|
-
hidden = root / ".monoco" / "project.yaml"
|
|
36
|
-
|
|
37
|
-
# Ensure parent exists
|
|
38
|
-
hidden.parent.mkdir(exist_ok=True)
|
|
39
|
-
return hidden
|
|
40
|
-
|
|
41
32
|
def update_config_repos(root: Path, repo_name: str, repo_url: str, remove: bool = False):
|
|
42
33
|
"""Update the repos list in the config file."""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
data = {}
|
|
46
|
-
if config_path.exists():
|
|
47
|
-
try:
|
|
48
|
-
with open(config_path, "r") as f:
|
|
49
|
-
data = yaml.safe_load(f) or {}
|
|
50
|
-
except Exception:
|
|
51
|
-
data = {}
|
|
34
|
+
# Use core config utils
|
|
35
|
+
data = load_raw_config(ConfigScope.PROJECT, project_root=str(root))
|
|
52
36
|
|
|
53
37
|
# Ensure structure exists
|
|
54
38
|
if "project" not in data:
|
|
@@ -62,8 +46,7 @@ def update_config_repos(root: Path, repo_name: str, repo_url: str, remove: bool
|
|
|
62
46
|
else:
|
|
63
47
|
data["project"]["spike_repos"][repo_name] = repo_url
|
|
64
48
|
|
|
65
|
-
|
|
66
|
-
yaml.dump(data, f, sort_keys=False, default_flow_style=False)
|
|
49
|
+
save_raw_config(ConfigScope.PROJECT, data, project_root=str(root))
|
|
67
50
|
|
|
68
51
|
def ensure_gitignore(root: Path, target_dir_name: str):
|
|
69
52
|
"""Ensure the target directory is in .gitignore."""
|
monoco/main.py
CHANGED
|
@@ -167,20 +167,5 @@ app.add_typer(agent_cmd.app, name="agent", help="Delegate tasks to Agent CLIs")
|
|
|
167
167
|
from monoco.daemon.commands import serve
|
|
168
168
|
app.command(name="serve")(serve)
|
|
169
169
|
|
|
170
|
-
@app.command()
|
|
171
|
-
def pty(
|
|
172
|
-
host: str = "127.0.0.1",
|
|
173
|
-
port: int = 3124,
|
|
174
|
-
cwd: Optional[str] = None
|
|
175
|
-
):
|
|
176
|
-
"""
|
|
177
|
-
Start the Monoco PTY Daemon (WebSocket).
|
|
178
|
-
"""
|
|
179
|
-
from monoco.features.pty.server import run_pty_server
|
|
180
|
-
from pathlib import Path
|
|
181
|
-
|
|
182
|
-
path = Path(cwd) if cwd else None
|
|
183
|
-
run_pty_server(host, port, path)
|
|
184
|
-
|
|
185
170
|
if __name__ == "__main__":
|
|
186
171
|
app()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: monoco-toolkit
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
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,18 +1,18 @@
|
|
|
1
|
-
monoco/main.py,sha256=
|
|
1
|
+
monoco/main.py,sha256=dM6UutWW2OJBG3yAUuYSXuw5pBfD1216PzwEWweY-lY,5761
|
|
2
2
|
monoco/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
monoco/cli/project.py,sha256=w4oUWzOV42qh34g4klyzZfTUg6ux0oEdSinMCzmhH3E,2786
|
|
4
4
|
monoco/cli/workspace.py,sha256=vhRsbjgO6ek6PWYdmhk9EeYW_xWRV196yl7-xPfcRAI,1305
|
|
5
5
|
monoco/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
monoco/core/config.py,sha256=
|
|
6
|
+
monoco/core/config.py,sha256=_0S-ogCAwP5FKpJiAGV2O5_v2fnJoU21NpNYnSse7_0,12767
|
|
7
7
|
monoco/core/execution.py,sha256=rySL0ueJvTEQ1JhdpumsNBQHJpj08nfaHQMlX-1uh6k,1846
|
|
8
8
|
monoco/core/feature.py,sha256=oAtQWUHMuqIFbq2gj8sPfYBlJZvMMXZqyUlCMrIVGUE,2007
|
|
9
9
|
monoco/core/git.py,sha256=i_NKT9_n57S9EKeb8kF2yTEdw70FZ88-lpMqW4lzVds,8228
|
|
10
10
|
monoco/core/injection.py,sha256=4BuQ5RVozyU99uSOzPwgc6MFMZUcECerTik5lF39I9A,7078
|
|
11
|
-
monoco/core/integrations.py,sha256=
|
|
12
|
-
monoco/core/lsp.py,sha256=
|
|
13
|
-
monoco/core/output.py,sha256=
|
|
11
|
+
monoco/core/integrations.py,sha256=MGw6dCipX2S5GtnboFwVxpkuWMGa_I6T9s0owsIjU4o,7885
|
|
12
|
+
monoco/core/lsp.py,sha256=23OxtVomvvE0GgAbdw_8-DclIac1SzjJGt8urbPKXEA,2006
|
|
13
|
+
monoco/core/output.py,sha256=S5jbOBRuLleBPfypS5nUUoNIUAdub4zJO63RePLb0LU,3787
|
|
14
14
|
monoco/core/registry.py,sha256=xix21TDeJgRiZ2kvHitnac4RsqMdp1aERpYGSrwfIpY,1180
|
|
15
|
-
monoco/core/setup.py,sha256=
|
|
15
|
+
monoco/core/setup.py,sha256=5fAsj4HZAC1sG-pEn5hKTZ6JsCAqNa8-eWOs739wpqs,9657
|
|
16
16
|
monoco/core/skills.py,sha256=5qK-0YlOnNQLqyo6-T4GVBrkjsbrszb5ugXeXRRcQ00,16597
|
|
17
17
|
monoco/core/state.py,sha256=KlmOn0KXO8g9S_KUIrUylAKdBpyH_1AOBvrYSj_khdE,1884
|
|
18
18
|
monoco/core/sync.py,sha256=s0qQ5PsVn_IWGWUNThdvNFS-CncztDzsTM3QLupC6Og,8514
|
|
@@ -20,7 +20,7 @@ monoco/core/telemetry.py,sha256=DZQGOhvpe0XL34RCDaTZEUhmkD4abBTZumZJQlALzpY,2923
|
|
|
20
20
|
monoco/core/workspace.py,sha256=0RWx8H_Kx56TYVrAURTSJW4aWOUylXofkvXBhRNjP_E,3074
|
|
21
21
|
monoco/core/agent/__init__.py,sha256=tBCm6PDqPFo81yO949nW897INjl7ot46CPup9IrXExE,108
|
|
22
22
|
monoco/core/agent/action.py,sha256=HpOLzp-mttJY0SDVbRlstDVqjFKozIAdjQdJ4Gp3xiY,5161
|
|
23
|
-
monoco/core/agent/adapters.py,sha256=
|
|
23
|
+
monoco/core/agent/adapters.py,sha256=s8dzeXZY-m1pb8re5U5O1ED4d6MT9WNFWIeSpHBcmRg,4391
|
|
24
24
|
monoco/core/agent/protocol.py,sha256=E7y_i2JzYGpzSCRCUIuzu1ATav-Xu1K01ka6Zncm4-o,831
|
|
25
25
|
monoco/core/agent/state.py,sha256=sRav6uwkXao8yPl08CEB-cqK1EfiDyMnVxoSYxvYcis,3523
|
|
26
26
|
monoco/core/resources/en/AGENTS.md,sha256=3TpCLNC1s_lIbDfJJBRmmROMoy9sZXu8BOag8M9NXI0,327
|
|
@@ -35,8 +35,19 @@ monoco/daemon/reproduce_stats.py,sha256=Q_zAj0Yj8l-77QDdtsLz1kWr68HeO7f1T6xC6VP4
|
|
|
35
35
|
monoco/daemon/services.py,sha256=dMhy2ddzGtBBWTGtI14R-2aikENAgPsphxDkno1JAPU,5377
|
|
36
36
|
monoco/daemon/stats.py,sha256=r-L0k6CdxkAkwLZV3V-jW7PldB9S3uNklQGLCEKA3Sc,4563
|
|
37
37
|
monoco/features/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
-
monoco/features/agent/commands.py,sha256=
|
|
38
|
+
monoco/features/agent/commands.py,sha256=31P1_vtg19YZZd7Z5uaDtwzGSpWLzI0sMfCp7Xppt-U,8572
|
|
39
|
+
monoco/features/agent/core.py,sha256=w_zZFsrZNFfV7nEP7HatvsMt_xsJlB8SCFGCCbXPUKo,1704
|
|
39
40
|
monoco/features/agent/doctor.py,sha256=qqUu_rUjVp7ur1sYpL4VSpw8vwbwbjvXAFvXQP-lbNQ,924
|
|
41
|
+
monoco/features/agent/resources/en/critique.prompty,sha256=lB1jkMsnufrelAzdo2FPD-pQ5agj6atBDnU_kvJNLK0,470
|
|
42
|
+
monoco/features/agent/resources/en/develop.prompty,sha256=T2vOYzf6xoTkImhT8ZmZSYRHev_DnG2mSF8LGji5vsU,480
|
|
43
|
+
monoco/features/agent/resources/en/investigate.prompty,sha256=l4DH4BUU-OCascYNC7rvqArA0COgAAPCLjJCPLV28Io,628
|
|
44
|
+
monoco/features/agent/resources/en/refine.prompty,sha256=PX2V1gUqs7McX_woPMlSVXKabyV0ly6ysBr35pGLa60,422
|
|
45
|
+
monoco/features/agent/resources/en/verify.prompty,sha256=-gb_HxhtdsJZ3_P3TtrhBjTRASkcKtr9v3c8jTQ4DtE,564
|
|
46
|
+
monoco/features/agent/resources/zh/critique.prompty,sha256=lNuQ_9Jl5LasJRwogh_JUM5WK0GNzJI6ZSI0Jy8HY7Y,485
|
|
47
|
+
monoco/features/agent/resources/zh/develop.prompty,sha256=-Mzqye5LZ_IMcNsDQY4xo97zncXaIe-tk9VK9fIxgME,477
|
|
48
|
+
monoco/features/agent/resources/zh/investigate.prompty,sha256=bHCVOxtL68iT8wg06sC0cTwvKCt27YF8CYu5LHMVxWY,650
|
|
49
|
+
monoco/features/agent/resources/zh/refine.prompty,sha256=YSC08M3k4KyN1KcfmSXqxjvzfC3m-GKTzO0LRBpeRFA,469
|
|
50
|
+
monoco/features/agent/resources/zh/verify.prompty,sha256=85yPcrvcaJW31-RD4G2lgXd2CJUTJFAnHlSIUpzApyg,629
|
|
40
51
|
monoco/features/config/commands.py,sha256=PQaSq81zH4h8d1bFa4B2ANSXSdyjBFqVm_nBvEq1rNE,4889
|
|
41
52
|
monoco/features/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
53
|
monoco/features/i18n/adapter.py,sha256=M9iSEKykEiUe1YobHKmvfEjv7x7KgGuh-6yhgUJuN_s,973
|
|
@@ -47,31 +58,39 @@ monoco/features/i18n/resources/en/SKILL.md,sha256=Z8fAAqeMvpLDw1D_9AzZIykS5-HLVM
|
|
|
47
58
|
monoco/features/i18n/resources/zh/AGENTS.md,sha256=lKkwLLCADRH7UDq9no4eQY2sRfJrb64JoZ_HNved8vA,175
|
|
48
59
|
monoco/features/i18n/resources/zh/SKILL.md,sha256=y2UuwhZmCBy0pXGxWLNrhxb94zcNfGEMBA_imJgDqVg,1894
|
|
49
60
|
monoco/features/issue/adapter.py,sha256=Y-ghwRoSEgm_A-cqY8Un-5srxydXdb9ytlKHLm89eJQ,1265
|
|
50
|
-
monoco/features/issue/commands.py,sha256=
|
|
51
|
-
monoco/features/issue/core.py,sha256=
|
|
52
|
-
monoco/features/issue/linter.py,sha256
|
|
61
|
+
monoco/features/issue/commands.py,sha256=SUq49ue2KElEe_I6WSADIoYj6-v54NKzOxInOjGsWvk,35495
|
|
62
|
+
monoco/features/issue/core.py,sha256=A-mWDg8aO19G8pibFagY-_6wAVu8bIn0CVCAyabhzB8,46365
|
|
63
|
+
monoco/features/issue/linter.py,sha256=-S3-DK0HKP_3EhSC69za8MyB-bVU4vOkNGM_Ajmjxoo,12056
|
|
53
64
|
monoco/features/issue/migration.py,sha256=9gtgFi1V1pzwXo0-H4cIoBvSBERIWopXLCB4oSxTQLc,4715
|
|
54
|
-
monoco/features/issue/models.py,sha256=
|
|
65
|
+
monoco/features/issue/models.py,sha256=bcQoCyzdgHIQ71tsZzdnxH4-5HgHaF_RlE2Fvg-lVdg,4968
|
|
55
66
|
monoco/features/issue/monitor.py,sha256=QEN0mqZ3tKwBfMjN87-LdrVoIEe0prA-uMHOBGy1VZk,3476
|
|
56
|
-
monoco/features/issue/validator.py,sha256=
|
|
67
|
+
monoco/features/issue/validator.py,sha256=6Q8LyjGpHXOf97q0-3bXvrWFqk7iO6fHhoGemkPTbps,17172
|
|
68
|
+
monoco/features/issue/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
|
+
monoco/features/issue/domain/lifecycle.py,sha256=-WreIDCeEQPjD82Q4wJMs_S5-9SQHCvGlPgtMllvXGw,4943
|
|
70
|
+
monoco/features/issue/domain/models.py,sha256=pjeb_Lp0zykNzAfrRma26IMkdlxYDQ0IdvNmM_7tepU,5720
|
|
71
|
+
monoco/features/issue/domain/parser.py,sha256=HfJh9uBN7Q7KyeXz1tk3tBjszu8ffStfZf9IS27v0K8,8770
|
|
72
|
+
monoco/features/issue/domain/workspace.py,sha256=AOv7H_he39UnYplCaEex6mdFgpAlGk6T8cDMxKwQLz0,3833
|
|
73
|
+
monoco/features/issue/engine/__init__.py,sha256=bWONZnIb0IkAhw09_pMbyqrDh-oUOLTrNvlQfypHXYw,785
|
|
74
|
+
monoco/features/issue/engine/config.py,sha256=6zGLmnswEAGfYrneG8a0GeA3qr8_BIv_n3Dta8Z7dlU,6420
|
|
75
|
+
monoco/features/issue/engine/machine.py,sha256=8wr5txLlzv0QO2sAlPl7JSPN-VkxJUpRNK25F7L7DVI,7530
|
|
76
|
+
monoco/features/issue/engine/models.py,sha256=u8Z7ilB702Jj6Imv4_vXpP8QTSWEnQdPxv8JA_9g1GU,579
|
|
77
|
+
monoco/features/issue/lsp/__init__.py,sha256=8bl8-WzSj3C4SkPKgVGnCeyemmvHVWBsuMZsJuJggG8,77
|
|
78
|
+
monoco/features/issue/lsp/definition.py,sha256=Y4dX7MmrEfYbWuh85W0djwUj_qed7cDpGadtiXEZDh4,3107
|
|
57
79
|
monoco/features/issue/resources/en/AGENTS.md,sha256=OjEnkXCqwfMArJfJQhldrQYXqoregfGthyhJeyx7MPw,715
|
|
58
80
|
monoco/features/issue/resources/en/SKILL.md,sha256=p0vhVpe3xLKg0iXSNofoLNvsq8j2pmv5CD1B2mUeIGk,2732
|
|
59
81
|
monoco/features/issue/resources/zh/AGENTS.md,sha256=2MLIZ5-i-oBnl7_YAZBBoKkNqANpHj73iw18QQbSm5c,759
|
|
60
82
|
monoco/features/issue/resources/zh/SKILL.md,sha256=_aXDThhsJag9OLK2X5LRVhaFyMcl4DcZvcSj1_UUkx8,3828
|
|
61
|
-
monoco/features/pty/core.py,sha256=eM1EvHQrgExSnatO15pyfhh1VZoz0BBTfNYdXqG8HZ8,5711
|
|
62
|
-
monoco/features/pty/router.py,sha256=7h80EPpOuE7hX5ifkxkzffcLZGecd5X8OmNvOji5ToI,5078
|
|
63
|
-
monoco/features/pty/server.py,sha256=kw2csMZ_R4_Xx6ta2dbznWtgNZLfrWOAkMp8NjlZYBc,1920
|
|
64
83
|
monoco/features/skills/__init__.py,sha256=L8YNGPWyyFWq5WqNossfeB0AKHJF_omrn1VzJBrRFcM,23
|
|
65
84
|
monoco/features/skills/core.py,sha256=mpd0Cq-k2MvHRTPq9saFvZgYXUBGJ9pnK5lUmzUfZbY,3418
|
|
66
85
|
monoco/features/spike/adapter.py,sha256=npJ4J775Df0DDi-LH-3u2jCuKjTIXyZUbLD0KNvHlcc,1062
|
|
67
86
|
monoco/features/spike/commands.py,sha256=ctC2Kbe0fgpeDfw5106P0rsKEBDue0rFI4eMNRpXMDw,3880
|
|
68
|
-
monoco/features/spike/core.py,sha256=
|
|
87
|
+
monoco/features/spike/core.py,sha256=oP1yAalOnoA5fHpf2o4gteKx73XGwZ6G0WrO86z2iWE,4174
|
|
69
88
|
monoco/features/spike/resources/en/AGENTS.md,sha256=NG3CMnlDk_0J8hnRUcueAM9lgIQr_dZ42R_31-LC48E,306
|
|
70
89
|
monoco/features/spike/resources/en/SKILL.md,sha256=qKDcVh0D3pDRvfNLh1Bzo4oQU3obpl4tqdlzxeiWYMk,1911
|
|
71
90
|
monoco/features/spike/resources/zh/AGENTS.md,sha256=5RHNl7fc3RdYYTFH483ojJl_arGPKkyYziOuGgFbqqg,290
|
|
72
91
|
monoco/features/spike/resources/zh/SKILL.md,sha256=boGPgAfTHbEzdwomRh-qVEveWSgvYaPUdi_4YZVXGHI,1714
|
|
73
|
-
monoco_toolkit-0.2.
|
|
74
|
-
monoco_toolkit-0.2.
|
|
75
|
-
monoco_toolkit-0.2.
|
|
76
|
-
monoco_toolkit-0.2.
|
|
77
|
-
monoco_toolkit-0.2.
|
|
92
|
+
monoco_toolkit-0.2.6.dist-info/METADATA,sha256=QjAPSxnTtN_ebkZlnWqqDP-xolO1d38oTLhT3LAMlMY,3743
|
|
93
|
+
monoco_toolkit-0.2.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
94
|
+
monoco_toolkit-0.2.6.dist-info/entry_points.txt,sha256=iYj7FWYBdtClU15-Du1skqD0s6SFSIhJvxJ29VWp8ng,43
|
|
95
|
+
monoco_toolkit-0.2.6.dist-info/licenses/LICENSE,sha256=ACAGGjV6aod4eIlVUTx1q9PZbnZGN5bBwkSs9RHj83s,1071
|
|
96
|
+
monoco_toolkit-0.2.6.dist-info/RECORD,,
|