monoco-toolkit 0.1.1__py3-none-any.whl → 0.2.5__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/cli/__init__.py +0 -0
- monoco/cli/project.py +87 -0
- monoco/cli/workspace.py +46 -0
- monoco/core/agent/__init__.py +5 -0
- monoco/core/agent/action.py +144 -0
- monoco/core/agent/adapters.py +106 -0
- monoco/core/agent/protocol.py +31 -0
- monoco/core/agent/state.py +106 -0
- monoco/core/config.py +152 -17
- monoco/core/execution.py +62 -0
- monoco/core/feature.py +58 -0
- monoco/core/git.py +51 -2
- monoco/core/injection.py +196 -0
- monoco/core/integrations.py +234 -0
- monoco/core/lsp.py +61 -0
- monoco/core/output.py +13 -2
- monoco/core/registry.py +36 -0
- monoco/core/resources/en/AGENTS.md +8 -0
- monoco/core/resources/en/SKILL.md +66 -0
- monoco/core/resources/zh/AGENTS.md +8 -0
- monoco/core/resources/zh/SKILL.md +66 -0
- monoco/core/setup.py +88 -110
- monoco/core/skills.py +444 -0
- monoco/core/state.py +53 -0
- monoco/core/sync.py +224 -0
- monoco/core/telemetry.py +4 -1
- monoco/core/workspace.py +85 -20
- monoco/daemon/app.py +127 -58
- monoco/daemon/models.py +4 -0
- monoco/daemon/services.py +56 -155
- monoco/features/agent/commands.py +166 -0
- monoco/features/agent/doctor.py +30 -0
- monoco/features/config/commands.py +125 -44
- monoco/features/i18n/adapter.py +29 -0
- monoco/features/i18n/commands.py +89 -10
- monoco/features/i18n/core.py +113 -27
- monoco/features/i18n/resources/en/AGENTS.md +8 -0
- monoco/features/i18n/resources/en/SKILL.md +94 -0
- monoco/features/i18n/resources/zh/AGENTS.md +8 -0
- monoco/features/i18n/resources/zh/SKILL.md +94 -0
- monoco/features/issue/adapter.py +34 -0
- monoco/features/issue/commands.py +183 -65
- monoco/features/issue/core.py +172 -77
- monoco/features/issue/linter.py +215 -116
- monoco/features/issue/migration.py +134 -0
- monoco/features/issue/models.py +23 -19
- monoco/features/issue/monitor.py +94 -0
- monoco/features/issue/resources/en/AGENTS.md +15 -0
- monoco/features/issue/resources/en/SKILL.md +87 -0
- monoco/features/issue/resources/zh/AGENTS.md +15 -0
- monoco/features/issue/resources/zh/SKILL.md +114 -0
- monoco/features/issue/validator.py +269 -0
- monoco/features/pty/core.py +185 -0
- monoco/features/pty/router.py +138 -0
- monoco/features/pty/server.py +56 -0
- monoco/features/spike/adapter.py +30 -0
- monoco/features/spike/commands.py +45 -24
- monoco/features/spike/core.py +4 -21
- monoco/features/spike/resources/en/AGENTS.md +7 -0
- monoco/features/spike/resources/en/SKILL.md +74 -0
- monoco/features/spike/resources/zh/AGENTS.md +7 -0
- monoco/features/spike/resources/zh/SKILL.md +74 -0
- monoco/main.py +115 -2
- {monoco_toolkit-0.1.1.dist-info → monoco_toolkit-0.2.5.dist-info}/METADATA +2 -2
- monoco_toolkit-0.2.5.dist-info/RECORD +77 -0
- monoco_toolkit-0.1.1.dist-info/RECORD +0 -33
- {monoco_toolkit-0.1.1.dist-info → monoco_toolkit-0.2.5.dist-info}/WHEEL +0 -0
- {monoco_toolkit-0.1.1.dist-info → monoco_toolkit-0.2.5.dist-info}/entry_points.txt +0 -0
- {monoco_toolkit-0.1.1.dist-info → monoco_toolkit-0.2.5.dist-info}/licenses/LICENSE +0 -0
monoco/core/setup.py
CHANGED
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import subprocess
|
|
3
3
|
import yaml
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
5
6
|
import typer
|
|
6
7
|
from rich.console import Console
|
|
7
8
|
from monoco.core.output import print_output
|
|
@@ -107,12 +108,18 @@ def ask_with_selection(message: str, default: str) -> str:
|
|
|
107
108
|
def init_cli(
|
|
108
109
|
ctx: typer.Context,
|
|
109
110
|
global_only: bool = typer.Option(False, "--global", help="Only configure global user settings"),
|
|
110
|
-
project_only: bool = typer.Option(False, "--project", help="Only configure current project")
|
|
111
|
+
project_only: bool = typer.Option(False, "--project", help="Only configure current project"),
|
|
112
|
+
# Non-interactive arguments
|
|
113
|
+
name: Optional[str] = typer.Option(None, "--name", "-n", help="Project Name"),
|
|
114
|
+
key: Optional[str] = typer.Option(None, "--key", "-k", help="Project Key"),
|
|
115
|
+
author: Optional[str] = typer.Option(None, "--author", "-a", help="Author Name"),
|
|
116
|
+
telemetry: Optional[bool] = typer.Option(None, "--telemetry/--no-telemetry", help="Enable/Disable telemetry")
|
|
111
117
|
):
|
|
112
118
|
"""
|
|
113
119
|
Initialize Monoco configuration (Global and/or Project).
|
|
114
120
|
"""
|
|
115
|
-
|
|
121
|
+
# Force non-interactive for now as requested
|
|
122
|
+
interactive = False
|
|
116
123
|
|
|
117
124
|
home_dir = Path.home() / ".monoco"
|
|
118
125
|
global_config_path = home_dir / "config.yaml"
|
|
@@ -126,17 +133,38 @@ def init_cli(
|
|
|
126
133
|
home_dir.mkdir(parents=True, exist_ok=True)
|
|
127
134
|
|
|
128
135
|
default_author = get_git_user() or os.getenv("USER", "developer")
|
|
129
|
-
author = ask_with_selection("Your Name (for issue tracking)", default_author)
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
if author is None:
|
|
138
|
+
if interactive:
|
|
139
|
+
author = ask_with_selection("Your Name (for issue tracking)", default_author)
|
|
140
|
+
else:
|
|
141
|
+
# Fallback or Error?
|
|
142
|
+
# For global author, we can use default if not provided, or error?
|
|
143
|
+
# User said "Directly error saying what field is missing"
|
|
144
|
+
# But author has a reasonable default. Let's try to use default if available, else error.
|
|
145
|
+
if not default_author:
|
|
146
|
+
console.print("[red]Error:[/red] Missing required field: --author")
|
|
147
|
+
raise typer.Exit(code=1)
|
|
148
|
+
author = default_author
|
|
149
|
+
|
|
150
|
+
if telemetry is None:
|
|
151
|
+
if interactive:
|
|
152
|
+
from rich.prompt import Confirm
|
|
153
|
+
telemetry = Confirm.ask("Enable anonymous telemetry to help improve Monoco?", default=True)
|
|
154
|
+
else:
|
|
155
|
+
# Default to True or False? Let's default to False for non-interactive safety or True?
|
|
156
|
+
# Usually explicit is better. Let's assume False if not specified in non-interactive.
|
|
157
|
+
# Or maybe we just skip it if not provided?
|
|
158
|
+
# Let's check user intent: "Report what field is missing".
|
|
159
|
+
# Telemetry is optional. Let's set it to False if missing.
|
|
160
|
+
telemetry = False
|
|
132
161
|
|
|
133
162
|
user_config = {
|
|
134
163
|
"core": {
|
|
135
164
|
"author": author,
|
|
136
|
-
# Editor is handled by env/config defaults, no need to prompt
|
|
137
165
|
},
|
|
138
166
|
"telemetry": {
|
|
139
|
-
"enabled":
|
|
167
|
+
"enabled": telemetry
|
|
140
168
|
}
|
|
141
169
|
}
|
|
142
170
|
|
|
@@ -151,30 +179,60 @@ def init_cli(
|
|
|
151
179
|
# --- 2. Project Configuration ---
|
|
152
180
|
cwd = Path.cwd()
|
|
153
181
|
project_config_dir = cwd / ".monoco"
|
|
154
|
-
|
|
182
|
+
workspace_config_path = project_config_dir / "workspace.yaml"
|
|
183
|
+
project_config_path = project_config_dir / "project.yaml"
|
|
155
184
|
|
|
156
185
|
# Check if we should init project
|
|
157
|
-
if project_config_path.exists():
|
|
158
|
-
if
|
|
159
|
-
|
|
160
|
-
|
|
186
|
+
if workspace_config_path.exists() or project_config_path.exists():
|
|
187
|
+
if interactive:
|
|
188
|
+
from rich.prompt import Confirm
|
|
189
|
+
if not Confirm.ask(f"Project/Workspace config already exists in [dim]{project_config_dir}[/dim]. Overwrite?"):
|
|
190
|
+
console.print("[yellow]Skipping project initialization.[/yellow]")
|
|
191
|
+
return
|
|
192
|
+
else:
|
|
193
|
+
console.print(f"[yellow]Project/Workspace config already exists in {project_config_dir}. Use manual edit or delete it to re-init.[/yellow]")
|
|
194
|
+
return
|
|
161
195
|
|
|
162
196
|
console.rule("[bold blue]Project Setup[/bold blue]")
|
|
163
197
|
|
|
164
198
|
default_name = cwd.name
|
|
165
|
-
|
|
199
|
+
|
|
200
|
+
if name is None:
|
|
201
|
+
if interactive:
|
|
202
|
+
name = ask_with_selection("Project Name", default_name)
|
|
203
|
+
else:
|
|
204
|
+
console.print("[red]Error:[/red] Missing required field: --name")
|
|
205
|
+
raise typer.Exit(code=1)
|
|
206
|
+
|
|
207
|
+
project_name = name
|
|
166
208
|
|
|
167
209
|
default_key = generate_key(project_name)
|
|
168
|
-
|
|
210
|
+
|
|
211
|
+
if key is None:
|
|
212
|
+
if interactive:
|
|
213
|
+
key = ask_with_selection("Project Key (prefix for issues)", default_key)
|
|
214
|
+
else:
|
|
215
|
+
console.print("[red]Error:[/red] Missing required field: --key")
|
|
216
|
+
raise typer.Exit(code=1)
|
|
217
|
+
|
|
218
|
+
project_key = key
|
|
169
219
|
|
|
170
220
|
|
|
171
221
|
project_config_dir.mkdir(exist_ok=True)
|
|
172
222
|
|
|
223
|
+
# 2a. Create project.yaml (Identity)
|
|
173
224
|
project_config = {
|
|
174
225
|
"project": {
|
|
175
226
|
"name": project_name,
|
|
176
227
|
"key": project_key
|
|
177
|
-
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
with open(project_config_path, "w") as f:
|
|
232
|
+
yaml.dump(project_config, f, default_flow_style=False)
|
|
233
|
+
|
|
234
|
+
# 2b. Create workspace.yaml (Environment)
|
|
235
|
+
workspace_config = {
|
|
178
236
|
"paths": {
|
|
179
237
|
"issues": "Issues",
|
|
180
238
|
"spikes": ".references",
|
|
@@ -182,104 +240,24 @@ def init_cli(
|
|
|
182
240
|
}
|
|
183
241
|
}
|
|
184
242
|
|
|
185
|
-
with open(
|
|
186
|
-
yaml.dump(
|
|
187
|
-
|
|
188
|
-
# 2b. Generate Config Template
|
|
189
|
-
template_path = project_config_dir / "config_template.yaml"
|
|
190
|
-
template_content = """# Monoco Configuration Template
|
|
191
|
-
# This file serves as a reference for all available configuration options.
|
|
192
|
-
# Rename this file to config.yaml to use it.
|
|
243
|
+
with open(workspace_config_path, "w") as f:
|
|
244
|
+
yaml.dump(workspace_config, f, default_flow_style=False)
|
|
193
245
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# Logging verbosity (DEBUG, INFO, WARNING, ERROR)
|
|
199
|
-
# log_level: "INFO"
|
|
200
|
-
|
|
201
|
-
# Preferred text editor
|
|
202
|
-
# editor: "vim"
|
|
203
|
-
|
|
204
|
-
project:
|
|
205
|
-
# The display name of the project
|
|
206
|
-
name: "My Project"
|
|
207
|
-
|
|
208
|
-
# The prefix used for issue IDs (e.g. MON-001)
|
|
209
|
-
key: "MON"
|
|
210
|
-
|
|
211
|
-
# Managed external research repositories (name -> url)
|
|
212
|
-
# spike_repos:
|
|
213
|
-
# react: "https://github.com/facebook/react"
|
|
214
|
-
|
|
215
|
-
paths:
|
|
216
|
-
# Directory for tracking issues
|
|
217
|
-
issues: "Issues"
|
|
218
|
-
|
|
219
|
-
# Directory for specifications/documents
|
|
220
|
-
specs: "SPECS"
|
|
221
|
-
|
|
222
|
-
# Directory for research references (spikes)
|
|
223
|
-
spikes: ".references"
|
|
224
|
-
|
|
225
|
-
i18n:
|
|
226
|
-
# Source language code
|
|
227
|
-
source_lang: "en"
|
|
228
|
-
|
|
229
|
-
# Target language codes for translation
|
|
230
|
-
target_langs:
|
|
231
|
-
- "zh"
|
|
232
|
-
|
|
233
|
-
ui:
|
|
234
|
-
# Custom Domain Terminology Mapping
|
|
235
|
-
# Use this to rename core concepts in the UI without changing internal logic.
|
|
236
|
-
dictionary:
|
|
237
|
-
# Entities
|
|
238
|
-
epic: "Saga"
|
|
239
|
-
feature: "Story"
|
|
240
|
-
chore: "Task"
|
|
241
|
-
fix: "Bug"
|
|
246
|
+
# 2c. Generate Config Template (Optional - might need update)
|
|
247
|
+
# For now, let's skip template generation or update it later.
|
|
248
|
+
# Or generate a workspace_template.yaml
|
|
242
249
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
review: "QA"
|
|
247
|
-
done: "Released"
|
|
248
|
-
"""
|
|
249
|
-
with open(template_path, "w") as f:
|
|
250
|
-
f.write(template_content)
|
|
250
|
+
console.print(f"[green]✓ Project initialized in {cwd}[/green]")
|
|
251
|
+
console.print(f"[dim] - Identity: .monoco/project.yaml[/dim]")
|
|
252
|
+
console.print(f"[dim] - Environment: .monoco/workspace.yaml[/dim]")
|
|
251
253
|
|
|
252
|
-
#
|
|
254
|
+
# Check for issue feature init (this logic was implicit in caller?)
|
|
255
|
+
# No, init_cli is the main logic.
|
|
253
256
|
|
|
254
|
-
#
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
# Initialize Issues
|
|
261
|
-
issues_path = cwd / project_config["paths"]["issues"]
|
|
262
|
-
issue_core.init(issues_path)
|
|
263
|
-
|
|
264
|
-
# Initialize Spikes
|
|
265
|
-
spikes_name = project_config["paths"]["spikes"]
|
|
266
|
-
spike_core.init(cwd, spikes_name)
|
|
267
|
-
|
|
268
|
-
# Initialize I18n
|
|
269
|
-
i18n_core.init(cwd)
|
|
270
|
-
|
|
271
|
-
# Initialize Skills & Agent Docs
|
|
272
|
-
resources = [
|
|
273
|
-
issue_core.get_resources(),
|
|
274
|
-
spike_core.get_resources(),
|
|
275
|
-
i18n_core.get_resources()
|
|
276
|
-
]
|
|
277
|
-
skills.init(cwd, resources)
|
|
278
|
-
|
|
279
|
-
console.print(f"[green]✓ Project config initialized at {project_config_path}[/green]")
|
|
280
|
-
console.print(f"[green]✓ Config template generated at {template_path}[/green]")
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
console.print(f"[green]Access configured! issues will be created as {project_key}-XXX[/green]")
|
|
257
|
+
# Initialize basic directories
|
|
258
|
+
(cwd / "Issues").mkdir(exist_ok=True)
|
|
259
|
+
(cwd / ".references").mkdir(exist_ok=True)
|
|
260
|
+
|
|
261
|
+
console.print("\n[bold green]✓ Monoco Project Initialized![/bold green]")
|
|
262
|
+
console.print(f"Access configured! issues will be created as [bold]{project_key}-XXX[/bold]")
|
|
285
263
|
|