monoco-toolkit 0.1.0__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.
Files changed (69) hide show
  1. monoco/cli/__init__.py +0 -0
  2. monoco/cli/project.py +87 -0
  3. monoco/cli/workspace.py +46 -0
  4. monoco/core/agent/__init__.py +5 -0
  5. monoco/core/agent/action.py +144 -0
  6. monoco/core/agent/adapters.py +106 -0
  7. monoco/core/agent/protocol.py +31 -0
  8. monoco/core/agent/state.py +106 -0
  9. monoco/core/config.py +152 -17
  10. monoco/core/execution.py +62 -0
  11. monoco/core/feature.py +58 -0
  12. monoco/core/git.py +51 -2
  13. monoco/core/injection.py +196 -0
  14. monoco/core/integrations.py +234 -0
  15. monoco/core/lsp.py +61 -0
  16. monoco/core/output.py +13 -2
  17. monoco/core/registry.py +36 -0
  18. monoco/core/resources/en/AGENTS.md +8 -0
  19. monoco/core/resources/en/SKILL.md +66 -0
  20. monoco/core/resources/zh/AGENTS.md +8 -0
  21. monoco/core/resources/zh/SKILL.md +66 -0
  22. monoco/core/setup.py +88 -110
  23. monoco/core/skills.py +444 -0
  24. monoco/core/state.py +53 -0
  25. monoco/core/sync.py +224 -0
  26. monoco/core/telemetry.py +4 -1
  27. monoco/core/workspace.py +85 -20
  28. monoco/daemon/app.py +127 -58
  29. monoco/daemon/models.py +4 -0
  30. monoco/daemon/services.py +56 -155
  31. monoco/features/agent/commands.py +166 -0
  32. monoco/features/agent/doctor.py +30 -0
  33. monoco/features/config/commands.py +125 -44
  34. monoco/features/i18n/adapter.py +29 -0
  35. monoco/features/i18n/commands.py +89 -10
  36. monoco/features/i18n/core.py +113 -27
  37. monoco/features/i18n/resources/en/AGENTS.md +8 -0
  38. monoco/features/i18n/resources/en/SKILL.md +94 -0
  39. monoco/features/i18n/resources/zh/AGENTS.md +8 -0
  40. monoco/features/i18n/resources/zh/SKILL.md +94 -0
  41. monoco/features/issue/adapter.py +34 -0
  42. monoco/features/issue/commands.py +183 -65
  43. monoco/features/issue/core.py +172 -77
  44. monoco/features/issue/linter.py +215 -116
  45. monoco/features/issue/migration.py +134 -0
  46. monoco/features/issue/models.py +23 -19
  47. monoco/features/issue/monitor.py +94 -0
  48. monoco/features/issue/resources/en/AGENTS.md +15 -0
  49. monoco/features/issue/resources/en/SKILL.md +87 -0
  50. monoco/features/issue/resources/zh/AGENTS.md +15 -0
  51. monoco/features/issue/resources/zh/SKILL.md +114 -0
  52. monoco/features/issue/validator.py +269 -0
  53. monoco/features/pty/core.py +185 -0
  54. monoco/features/pty/router.py +138 -0
  55. monoco/features/pty/server.py +56 -0
  56. monoco/features/spike/adapter.py +30 -0
  57. monoco/features/spike/commands.py +45 -24
  58. monoco/features/spike/core.py +4 -21
  59. monoco/features/spike/resources/en/AGENTS.md +7 -0
  60. monoco/features/spike/resources/en/SKILL.md +74 -0
  61. monoco/features/spike/resources/zh/AGENTS.md +7 -0
  62. monoco/features/spike/resources/zh/SKILL.md +74 -0
  63. monoco/main.py +115 -2
  64. {monoco_toolkit-0.1.0.dist-info → monoco_toolkit-0.2.5.dist-info}/METADATA +10 -3
  65. monoco_toolkit-0.2.5.dist-info/RECORD +77 -0
  66. monoco_toolkit-0.1.0.dist-info/RECORD +0 -33
  67. {monoco_toolkit-0.1.0.dist-info → monoco_toolkit-0.2.5.dist-info}/WHEEL +0 -0
  68. {monoco_toolkit-0.1.0.dist-info → monoco_toolkit-0.2.5.dist-info}/entry_points.txt +0 -0
  69. {monoco_toolkit-0.1.0.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
- from rich.prompt import Confirm
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
- telemetry_enabled = Confirm.ask("Enable anonymous telemetry to help improve Monoco?", default=True)
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": telemetry_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
- project_config_path = project_config_dir / "config.yaml"
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 not Confirm.ask(f"Project config already exists at [dim]{project_config_path}[/dim]. Overwrite?"):
159
- console.print("[yellow]Skipping project initialization.[/yellow]")
160
- return
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
- project_name = ask_with_selection("Project Name", default_name)
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
- project_key = ask_with_selection("Project Key (prefix for issues)", default_key)
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(project_config_path, "w") as f:
186
- yaml.dump(project_config, f, default_flow_style=False)
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
- core:
195
- # Default author for new artifacts (e.g. issues)
196
- # author: "Developer Name"
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
- # Statuses
244
- todo: "Pending"
245
- doing: "In Progress"
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
- # 3. Scaffold Directories & Modules
254
+ # Check for issue feature init (this logic was implicit in caller?)
255
+ # No, init_cli is the main logic.
253
256
 
254
- # Import Feature Cores locally to avoid circular deps if any (though setup is core)
255
- from monoco.features.issue import core as issue_core
256
- from monoco.features.spike import core as spike_core
257
- from monoco.features.i18n import core as i18n_core
258
- from monoco.features import skills
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