moai-adk 0.8.0__py3-none-any.whl → 0.15.0__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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/cli/commands/init.py +14 -2
- moai_adk/cli/commands/update.py +229 -60
- moai_adk/core/config/migration.py +1 -1
- moai_adk/core/issue_creator.py +313 -0
- moai_adk/core/project/detector.py +201 -12
- moai_adk/core/project/initializer.py +62 -1
- moai_adk/core/project/phase_executor.py +48 -6
- moai_adk/core/tags/__init__.py +86 -0
- moai_adk/core/tags/ci_validator.py +463 -0
- moai_adk/core/tags/cli.py +283 -0
- moai_adk/core/tags/generator.py +109 -0
- moai_adk/core/tags/inserter.py +99 -0
- moai_adk/core/tags/mapper.py +126 -0
- moai_adk/core/tags/parser.py +76 -0
- moai_adk/core/tags/pre_commit_validator.py +393 -0
- moai_adk/core/tags/reporter.py +956 -0
- moai_adk/core/tags/tags.py +149 -0
- moai_adk/core/tags/validator.py +897 -0
- moai_adk/core/template_engine.py +268 -0
- moai_adk/templates/.claude/agents/alfred/backend-expert.md +319 -0
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +25 -2
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +24 -12
- moai_adk/templates/.claude/agents/alfred/devops-expert.md +464 -0
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +20 -13
- moai_adk/templates/.claude/agents/alfred/frontend-expert.md +357 -0
- moai_adk/templates/.claude/agents/alfred/git-manager.md +47 -16
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +95 -15
- moai_adk/templates/.claude/agents/alfred/project-manager.md +78 -12
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +28 -5
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +30 -2
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +133 -13
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +104 -8
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +133 -16
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +27 -4
- moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +571 -0
- moai_adk/templates/.claude/commands/alfred/0-project.md +466 -125
- moai_adk/templates/.claude/commands/alfred/1-plan.md +208 -71
- moai_adk/templates/.claude/commands/alfred/2-run.md +276 -55
- moai_adk/templates/.claude/commands/alfred/3-sync.md +439 -53
- moai_adk/templates/.claude/commands/alfred/9-feedback.md +149 -0
- moai_adk/templates/.claude/hooks/alfred/core/project.py +361 -29
- moai_adk/templates/.claude/hooks/alfred/core/timeout.py +136 -0
- moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +108 -0
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +14 -6
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +100 -0
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/__init__.py +2 -2
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +3 -3
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +5 -5
- moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +749 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/tags.py +55 -23
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +21 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +154 -0
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/session.py +28 -15
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/tool.py +3 -6
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/user.py +19 -0
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +112 -0
- moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +1 -0
- moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +161 -0
- moai_adk/templates/.claude/settings.json +5 -5
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +70 -0
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +62 -0
- moai_adk/templates/{.moai/memory/CLAUDE-AGENTS-GUIDE.md → .claude/skills/moai-alfred-agent-guide/reference.md} +34 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +56 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +62 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +405 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +51 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +355 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +239 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +286 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +126 -0
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/SKILL.md +74 -0
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/reference.md +269 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +150 -0
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/SKILL.md +198 -0
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/examples.md +431 -0
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/reference.md +141 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +89 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +122 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +508 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +481 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +100 -0
- moai_adk/templates/.claude/skills/moai-alfred-reporting/SKILL.md +273 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +77 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +265 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +84 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +137 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +219 -0
- moai_adk/templates/.claude/skills/{moai-spec-authoring → moai-alfred-spec-authoring}/examples/validate-spec.sh +3 -3
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +541 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +622 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/SKILL.md +115 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/reference.md +348 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +211 -0
- moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/examples.md +4 -0
- moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/SKILL.md +3 -3
- moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +802 -0
- moai_adk/templates/.claude/skills/moai-design-systems/examples.md +1238 -0
- moai_adk/templates/.claude/skills/moai-design-systems/reference.md +673 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +17 -13
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +9 -6
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +15 -12
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +14 -12
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +14 -11
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +10 -8
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +15 -12
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +13 -11
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +16 -10
- moai_adk/templates/.claude/skills/moai-project-documentation.md +622 -0
- moai_adk/templates/.git-hooks/pre-push +143 -0
- moai_adk/templates/.github/workflows/c-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/cpp-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/csharp-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/dart-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/go-tag-validation.yml +130 -0
- moai_adk/templates/.github/workflows/java-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/javascript-tag-validation.yml +135 -0
- moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/moai-gitflow.yml +166 -3
- moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +188 -0
- moai_adk/templates/.github/workflows/php-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/python-tag-validation.yml +118 -0
- moai_adk/templates/.github/workflows/release.yml +118 -0
- moai_adk/templates/.github/workflows/ruby-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/rust-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/shell-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +206 -35
- moai_adk/templates/.github/workflows/swift-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/tag-report.yml +269 -0
- moai_adk/templates/.github/workflows/tag-validation.yml +186 -0
- moai_adk/templates/.github/workflows/typescript-tag-validation.yml +154 -0
- moai_adk/templates/.moai/config.json +21 -2
- moai_adk/templates/CLAUDE.md +972 -78
- moai_adk/templates/workflows/go-tag-validation.yml +30 -0
- moai_adk/templates/workflows/javascript-tag-validation.yml +41 -0
- moai_adk/templates/workflows/python-tag-validation.yml +42 -0
- moai_adk/templates/workflows/typescript-tag-validation.yml +31 -0
- moai_adk/utils/banner.py +5 -5
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/METADATA +1518 -161
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/RECORD +183 -100
- moai_adk/templates/.claude/hooks/alfred/HOOK_SCHEMA_VALIDATION.md +0 -313
- moai_adk/templates/.claude/hooks/alfred/README.md +0 -230
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +0 -174
- moai_adk/templates/.claude/hooks/alfred/handlers/notification.py +0 -25
- moai_adk/templates/.claude/hooks/alfred/test_hook_output.py +0 -175
- moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +0 -640
- moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +0 -696
- moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +0 -474
- moai_adk/templates/.claude/skills/moai-spec-authoring/README.md +0 -137
- moai_adk/templates/.claude/skills/moai-spec-authoring/SKILL.md +0 -218
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples.md +0 -541
- moai_adk/templates/.claude/skills/moai-spec-authoring/reference.md +0 -622
- moai_adk/templates/.github/ISSUE_TEMPLATE/spec.yml +0 -176
- moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -69
- moai_adk/templates/.moai/memory/DEVELOPMENT-GUIDE.md +0 -344
- moai_adk/templates/.moai/memory/GITFLOW-PROTECTION-POLICY.md +0 -220
- moai_adk/templates/.moai/memory/SPEC-METADATA.md +0 -356
- moai_adk/templates/.moai/memory/config-schema.md +0 -444
- moai_adk/templates/.moai/memory/gitflow-protection-policy.md +0 -220
- moai_adk/templates/.moai/memory/spec-metadata.md +0 -356
- moai_adk/templates/.moai/project/product.md +0 -161
- moai_adk/templates/.moai/project/structure.md +0 -156
- moai_adk/templates/.moai/project/tech.md +0 -227
- moai_adk/templates/__init__.py +0 -2
- /moai_adk/templates/{.moai/memory/CONFIG-SCHEMA.md → .claude/skills/moai-alfred-config-schema/reference.md} +0 -0
- /moai_adk/templates/{.moai/memory/CLAUDE-PRACTICES.md → .claude/skills/moai-alfred-practices/reference.md} +0 -0
- /moai_adk/templates/{.moai/memory/CLAUDE-RULES.md → .claude/skills/moai-alfred-rules/reference.md} +0 -0
- /moai_adk/templates/{.moai/memory/SKILLS-DESCRIPTION-POLICY.md → .claude/skills/moai-cc-skill-descriptions/reference.md} +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/CHECKLIST.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/EXAMPLES.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/INTERACTIVE-DISCOVERY.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/METADATA.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/PARALLEL-ANALYSIS-REPORT.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/PYTHON-VERSION-MATRIX.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/SKILL-FACTORY-WORKFLOW.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/SKILL-UPDATE-ADVISOR.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/STEP-BY-STEP-GUIDE.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/STRUCTURE.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/WEB-RESEARCH.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/reference.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/scripts/generate-structure.sh +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/scripts/validate-skill.sh +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/SKILL_TEMPLATE.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/examples-template.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/reference-template.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/scripts-template.sh +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/WHEEL +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"""
|
|
2
|
+
GitHub Issue Creator for MoAI-ADK quick issue reporting.
|
|
3
|
+
|
|
4
|
+
Enables users to quickly create GitHub Issues with standardized templates
|
|
5
|
+
using `/alfred:9-feedback` interactive dialog.
|
|
6
|
+
|
|
7
|
+
@TAG:ISSUE-CREATOR-001 - GitHub issue creation system
|
|
8
|
+
@TAG:QUICK-REPORTING-001 - Quick issue reporting functionality
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import subprocess
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from enum import Enum
|
|
14
|
+
from typing import Any, Dict, List, Optional
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class IssueType(Enum):
|
|
18
|
+
"""Supported GitHub issue types."""
|
|
19
|
+
BUG = "bug"
|
|
20
|
+
FEATURE = "feature"
|
|
21
|
+
IMPROVEMENT = "improvement"
|
|
22
|
+
QUESTION = "question"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class IssuePriority(Enum):
|
|
26
|
+
"""Issue priority levels."""
|
|
27
|
+
CRITICAL = "critical"
|
|
28
|
+
HIGH = "high"
|
|
29
|
+
MEDIUM = "medium"
|
|
30
|
+
LOW = "low"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class IssueConfig:
|
|
35
|
+
"""Configuration for issue creation."""
|
|
36
|
+
issue_type: IssueType
|
|
37
|
+
title: str
|
|
38
|
+
description: str
|
|
39
|
+
priority: IssuePriority = IssuePriority.MEDIUM
|
|
40
|
+
category: Optional[str] = None
|
|
41
|
+
assignees: Optional[List[str]] = None
|
|
42
|
+
custom_labels: Optional[List[str]] = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class GitHubIssueCreator:
|
|
46
|
+
"""
|
|
47
|
+
Creates GitHub Issues using the `gh` CLI.
|
|
48
|
+
|
|
49
|
+
Supports:
|
|
50
|
+
- Multiple issue types (bug, feature, improvement, question)
|
|
51
|
+
- Priority levels and categories
|
|
52
|
+
- Standard templates for each type
|
|
53
|
+
- Label automation
|
|
54
|
+
- Priority emoji indicators
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
# Label mapping for issue types
|
|
58
|
+
LABEL_MAP = {
|
|
59
|
+
IssueType.BUG: ["bug", "reported"],
|
|
60
|
+
IssueType.FEATURE: ["feature-request", "enhancement"],
|
|
61
|
+
IssueType.IMPROVEMENT: ["improvement", "enhancement"],
|
|
62
|
+
IssueType.QUESTION: ["question", "help wanted"], # Fixed: "help-wanted" → "help wanted" (GitHub standard)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Priority emoji
|
|
66
|
+
PRIORITY_EMOJI = {
|
|
67
|
+
IssuePriority.CRITICAL: "🔴",
|
|
68
|
+
IssuePriority.HIGH: "🟠",
|
|
69
|
+
IssuePriority.MEDIUM: "🟡",
|
|
70
|
+
IssuePriority.LOW: "🟢",
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Issue type emoji
|
|
74
|
+
TYPE_EMOJI = {
|
|
75
|
+
IssueType.BUG: "🐛",
|
|
76
|
+
IssueType.FEATURE: "✨",
|
|
77
|
+
IssueType.IMPROVEMENT: "⚡",
|
|
78
|
+
IssueType.QUESTION: "❓",
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
def __init__(self, github_token: Optional[str] = None):
|
|
82
|
+
"""
|
|
83
|
+
Initialize the GitHub Issue Creator.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
github_token: GitHub API token. If not provided, uses GITHUB_TOKEN env var.
|
|
87
|
+
"""
|
|
88
|
+
self.github_token = github_token
|
|
89
|
+
self._check_gh_cli()
|
|
90
|
+
|
|
91
|
+
def _check_gh_cli(self) -> None:
|
|
92
|
+
"""
|
|
93
|
+
Check if `gh` CLI is installed and accessible.
|
|
94
|
+
|
|
95
|
+
Raises:
|
|
96
|
+
RuntimeError: If `gh` CLI is not found or not authenticated.
|
|
97
|
+
"""
|
|
98
|
+
try:
|
|
99
|
+
result = subprocess.run(
|
|
100
|
+
["gh", "auth", "status"],
|
|
101
|
+
capture_output=True,
|
|
102
|
+
text=True,
|
|
103
|
+
timeout=5
|
|
104
|
+
)
|
|
105
|
+
if result.returncode != 0:
|
|
106
|
+
raise RuntimeError(
|
|
107
|
+
"GitHub CLI (gh) is not authenticated. "
|
|
108
|
+
"Run `gh auth login` to authenticate."
|
|
109
|
+
)
|
|
110
|
+
except FileNotFoundError:
|
|
111
|
+
raise RuntimeError(
|
|
112
|
+
"GitHub CLI (gh) is not installed. "
|
|
113
|
+
"Please install it: https://cli.github.com"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def create_issue(self, config: IssueConfig) -> Dict[str, Any]:
|
|
117
|
+
"""
|
|
118
|
+
Create a GitHub issue with the given configuration.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
config: Issue configuration
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Dictionary containing issue creation result:
|
|
125
|
+
{
|
|
126
|
+
"success": bool,
|
|
127
|
+
"issue_number": int,
|
|
128
|
+
"issue_url": str,
|
|
129
|
+
"message": str
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
RuntimeError: If issue creation fails
|
|
134
|
+
"""
|
|
135
|
+
# Build title with emoji and priority
|
|
136
|
+
emoji = self.TYPE_EMOJI.get(config.issue_type, "📋")
|
|
137
|
+
priority_emoji = self.PRIORITY_EMOJI.get(config.priority, "")
|
|
138
|
+
full_title = f"{emoji} [{config.issue_type.value.upper()}] {config.title}"
|
|
139
|
+
if priority_emoji:
|
|
140
|
+
full_title = f"{priority_emoji} {full_title}"
|
|
141
|
+
|
|
142
|
+
# Build body with template
|
|
143
|
+
body = self._build_body(config)
|
|
144
|
+
|
|
145
|
+
# Collect labels
|
|
146
|
+
labels = self.LABEL_MAP.get(config.issue_type, []).copy()
|
|
147
|
+
if config.priority:
|
|
148
|
+
labels.append(config.priority.value) # Fixed: removed "priority-" prefix (use direct label names)
|
|
149
|
+
if config.category:
|
|
150
|
+
labels.append(f"category-{config.category.lower().replace(' ', '-')}")
|
|
151
|
+
if config.custom_labels:
|
|
152
|
+
labels.extend(config.custom_labels)
|
|
153
|
+
|
|
154
|
+
# Build gh command
|
|
155
|
+
gh_command = [
|
|
156
|
+
"gh", "issue", "create",
|
|
157
|
+
"--title", full_title,
|
|
158
|
+
"--body", body,
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
# Add labels
|
|
162
|
+
if labels:
|
|
163
|
+
gh_command.extend(["--label", ",".join(set(labels))])
|
|
164
|
+
|
|
165
|
+
# Add assignees if provided
|
|
166
|
+
if config.assignees:
|
|
167
|
+
gh_command.extend(["--assignee", ",".join(config.assignees)])
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
result = subprocess.run(
|
|
171
|
+
gh_command,
|
|
172
|
+
capture_output=True,
|
|
173
|
+
text=True,
|
|
174
|
+
timeout=30
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if result.returncode != 0:
|
|
178
|
+
error_msg = result.stderr or result.stdout
|
|
179
|
+
raise RuntimeError(f"Failed to create GitHub issue: {error_msg}")
|
|
180
|
+
|
|
181
|
+
# Parse issue URL from output
|
|
182
|
+
issue_url = result.stdout.strip()
|
|
183
|
+
issue_number = self._extract_issue_number(issue_url)
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
"success": True,
|
|
187
|
+
"issue_number": issue_number,
|
|
188
|
+
"issue_url": issue_url,
|
|
189
|
+
"message": f"✅ GitHub Issue #{issue_number} created successfully",
|
|
190
|
+
"title": full_title,
|
|
191
|
+
"labels": labels,
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
except subprocess.TimeoutExpired:
|
|
195
|
+
raise RuntimeError("GitHub issue creation timed out")
|
|
196
|
+
except Exception as e:
|
|
197
|
+
raise RuntimeError(f"Error creating GitHub issue: {e}")
|
|
198
|
+
|
|
199
|
+
def _build_body(self, config: IssueConfig) -> str:
|
|
200
|
+
"""
|
|
201
|
+
Build the issue body based on issue type.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
config: Issue configuration
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Formatted issue body
|
|
208
|
+
"""
|
|
209
|
+
body = config.description
|
|
210
|
+
|
|
211
|
+
# Add metadata footer
|
|
212
|
+
footer = "\n\n---\n\n"
|
|
213
|
+
footer += f"**Type**: {config.issue_type.value} \n"
|
|
214
|
+
footer += f"**Priority**: {config.priority.value} \n"
|
|
215
|
+
if config.category:
|
|
216
|
+
footer += f"**Category**: {config.category} \n"
|
|
217
|
+
footer += "**Created via**: `/alfred:9-feedback`"
|
|
218
|
+
|
|
219
|
+
return body + footer
|
|
220
|
+
|
|
221
|
+
@staticmethod
|
|
222
|
+
def _extract_issue_number(url: str) -> int:
|
|
223
|
+
"""
|
|
224
|
+
Extract issue number from GitHub URL.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
url: GitHub issue URL
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
Issue number
|
|
231
|
+
|
|
232
|
+
Raises:
|
|
233
|
+
ValueError: If unable to extract issue number
|
|
234
|
+
"""
|
|
235
|
+
try:
|
|
236
|
+
# URL format: https://github.com/owner/repo/issues/123
|
|
237
|
+
return int(url.strip().split("/")[-1])
|
|
238
|
+
except (ValueError, IndexError):
|
|
239
|
+
raise ValueError(f"Unable to extract issue number from URL: {url}")
|
|
240
|
+
|
|
241
|
+
def format_result(self, result: Dict[str, Any]) -> str:
|
|
242
|
+
"""
|
|
243
|
+
Format the issue creation result for display.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
result: Issue creation result
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
Formatted result string
|
|
250
|
+
"""
|
|
251
|
+
if result["success"]:
|
|
252
|
+
output = f"{result['message']}\n"
|
|
253
|
+
output += f"📋 Title: {result['title']}\n"
|
|
254
|
+
output += f"🔗 URL: {result['issue_url']}\n"
|
|
255
|
+
if result.get("labels"):
|
|
256
|
+
output += f"🏷️ Labels: {', '.join(result['labels'])}\n"
|
|
257
|
+
return output
|
|
258
|
+
else:
|
|
259
|
+
return f"❌ Failed to create issue: {result.get('message', 'Unknown error')}"
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class IssueCreatorFactory:
|
|
263
|
+
"""
|
|
264
|
+
Factory for creating issue creators with predefined configurations.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
@staticmethod
|
|
268
|
+
def create_bug_issue(title: str, description: str, priority: IssuePriority = IssuePriority.HIGH) -> IssueConfig:
|
|
269
|
+
"""Create a bug report issue configuration."""
|
|
270
|
+
return IssueConfig(
|
|
271
|
+
issue_type=IssueType.BUG,
|
|
272
|
+
title=title,
|
|
273
|
+
description=description,
|
|
274
|
+
priority=priority,
|
|
275
|
+
category="Bug Report",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
@staticmethod
|
|
279
|
+
def create_feature_issue(
|
|
280
|
+
title: str, description: str, priority: IssuePriority = IssuePriority.MEDIUM
|
|
281
|
+
) -> IssueConfig:
|
|
282
|
+
"""Create a feature request issue configuration."""
|
|
283
|
+
return IssueConfig(
|
|
284
|
+
issue_type=IssueType.FEATURE,
|
|
285
|
+
title=title,
|
|
286
|
+
description=description,
|
|
287
|
+
priority=priority,
|
|
288
|
+
category="Feature Request",
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
@staticmethod
|
|
292
|
+
def create_improvement_issue(
|
|
293
|
+
title: str, description: str, priority: IssuePriority = IssuePriority.MEDIUM
|
|
294
|
+
) -> IssueConfig:
|
|
295
|
+
"""Create an improvement issue configuration."""
|
|
296
|
+
return IssueConfig(
|
|
297
|
+
issue_type=IssueType.IMPROVEMENT,
|
|
298
|
+
title=title,
|
|
299
|
+
description=description,
|
|
300
|
+
priority=priority,
|
|
301
|
+
category="Improvement",
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
@staticmethod
|
|
305
|
+
def create_question_issue(title: str, description: str, priority: IssuePriority = IssuePriority.LOW) -> IssueConfig:
|
|
306
|
+
"""Create a question/discussion issue configuration."""
|
|
307
|
+
return IssueConfig(
|
|
308
|
+
issue_type=IssueType.QUESTION,
|
|
309
|
+
title=title,
|
|
310
|
+
description=description,
|
|
311
|
+
priority=priority,
|
|
312
|
+
category="Question",
|
|
313
|
+
)
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# @CODE:CORE-PROJECT-001 | SPEC: SPEC-CORE-PROJECT-001.md | TEST: tests/unit/test_language_detector.py
|
|
2
2
|
# @CODE:LANG-DETECT-001 | SPEC: SPEC-LANG-DETECT-001.md | TEST: tests/unit/test_detector.py
|
|
3
|
+
# @CODE:LDE-EXTENDED-001 | SPEC: SPEC-LANGUAGE-DETECTION-EXTENDED-001/spec.md | TEST: tests/unit/test_language_detector_extended.py
|
|
3
4
|
"""Language detector module.
|
|
4
5
|
|
|
5
6
|
Automatically detects 20 programming languages.
|
|
7
|
+
|
|
8
|
+
Extended detection supports:
|
|
9
|
+
- 11 new languages: Ruby, PHP, Java, Rust, Dart, Swift, Kotlin, C#, C, C++, Shell
|
|
10
|
+
- 5 build tool detection: Maven, Gradle, CMake, SPM, dotnet
|
|
11
|
+
- Package manager detection: bundle, composer, cargo
|
|
12
|
+
- Priority conflict resolution for multi-language projects
|
|
6
13
|
"""
|
|
7
14
|
|
|
8
15
|
from pathlib import Path
|
|
@@ -16,7 +23,18 @@ class LanguageDetector:
|
|
|
16
23
|
"""
|
|
17
24
|
|
|
18
25
|
LANGUAGE_PATTERNS = {
|
|
19
|
-
#
|
|
26
|
+
# @CODE:LDE-PRIORITY-001 | SPEC: SPEC-LANGUAGE-DETECTION-EXTENDED-001/spec.md
|
|
27
|
+
# Priority order (highest to lowest):
|
|
28
|
+
# 1. Rust, 2. Dart, 3. Swift, 4. Kotlin, 5. C#, 6. Java, 7. Ruby, 8. PHP
|
|
29
|
+
# 9. Go, 10. Python, 11. TypeScript, 12. JavaScript, 13. C++, 14. C, 15. Shell
|
|
30
|
+
|
|
31
|
+
"rust": ["*.rs", "Cargo.toml"],
|
|
32
|
+
"dart": ["*.dart", "pubspec.yaml"],
|
|
33
|
+
"swift": ["*.swift", "Package.swift"],
|
|
34
|
+
"kotlin": ["*.kt", "build.gradle.kts"],
|
|
35
|
+
"csharp": ["*.cs", "*.csproj"],
|
|
36
|
+
"java": ["*.java", "pom.xml", "build.gradle"],
|
|
37
|
+
# Ruby moved for priority (Rails detection)
|
|
20
38
|
# @CODE:LANG-DETECT-RUBY-001 | SPEC: Issue #51 Language Detection Fix
|
|
21
39
|
"ruby": [
|
|
22
40
|
"*.rb",
|
|
@@ -26,7 +44,7 @@ class LanguageDetector:
|
|
|
26
44
|
"app/controllers/", # Rails: controller directory
|
|
27
45
|
"Rakefile" # Rails/Ruby: task file
|
|
28
46
|
],
|
|
29
|
-
# PHP
|
|
47
|
+
# PHP after Ruby (Laravel detection)
|
|
30
48
|
"php": [
|
|
31
49
|
"*.php",
|
|
32
50
|
"composer.json",
|
|
@@ -34,23 +52,18 @@ class LanguageDetector:
|
|
|
34
52
|
"app/", # Laravel: application directory
|
|
35
53
|
"bootstrap/laravel.php" # Laravel: bootstrap file
|
|
36
54
|
],
|
|
55
|
+
"go": ["*.go", "go.mod"],
|
|
37
56
|
"python": ["*.py", "pyproject.toml", "requirements.txt", "setup.py"],
|
|
38
57
|
"typescript": ["*.ts", "tsconfig.json"],
|
|
39
58
|
"javascript": ["*.js", "package.json"],
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
"swift": ["*.swift", "Package.swift"],
|
|
45
|
-
"kotlin": ["*.kt", "build.gradle.kts"],
|
|
46
|
-
"csharp": ["*.cs", "*.csproj"],
|
|
59
|
+
"cpp": ["*.cpp", "CMakeLists.txt"],
|
|
60
|
+
"c": ["*.c", "Makefile"],
|
|
61
|
+
"shell": ["*.sh", "*.bash"],
|
|
62
|
+
# Additional languages (lower priority)
|
|
47
63
|
"elixir": ["*.ex", "mix.exs"],
|
|
48
64
|
"scala": ["*.scala", "build.sbt"],
|
|
49
65
|
"clojure": ["*.clj", "project.clj"],
|
|
50
66
|
"haskell": ["*.hs", "*.cabal"],
|
|
51
|
-
"c": ["*.c", "Makefile"],
|
|
52
|
-
"cpp": ["*.cpp", "CMakeLists.txt"],
|
|
53
|
-
"shell": ["*.sh", "*.bash"],
|
|
54
67
|
"lua": ["*.lua"],
|
|
55
68
|
}
|
|
56
69
|
|
|
@@ -112,6 +125,182 @@ class LanguageDetector:
|
|
|
112
125
|
|
|
113
126
|
return False
|
|
114
127
|
|
|
128
|
+
def get_workflow_template_path(self, language: str) -> str:
|
|
129
|
+
"""Get the GitHub Actions workflow template path for a language.
|
|
130
|
+
|
|
131
|
+
@CODE:LDE-WORKFLOW-PATH-001 | SPEC: SPEC-LANGUAGE-DETECTION-EXTENDED-001/spec.md
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
language: Programming language name (lowercase).
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Workflow template file path relative to templates directory.
|
|
138
|
+
|
|
139
|
+
Raises:
|
|
140
|
+
ValueError: If language is not supported for workflows.
|
|
141
|
+
"""
|
|
142
|
+
workflow_mapping = {
|
|
143
|
+
"python": ".github/workflows/python-tag-validation.yml",
|
|
144
|
+
"javascript": ".github/workflows/javascript-tag-validation.yml",
|
|
145
|
+
"typescript": ".github/workflows/typescript-tag-validation.yml",
|
|
146
|
+
"go": ".github/workflows/go-tag-validation.yml",
|
|
147
|
+
"ruby": ".github/workflows/ruby-tag-validation.yml",
|
|
148
|
+
"php": ".github/workflows/php-tag-validation.yml",
|
|
149
|
+
"java": ".github/workflows/java-tag-validation.yml",
|
|
150
|
+
"rust": ".github/workflows/rust-tag-validation.yml",
|
|
151
|
+
"dart": ".github/workflows/dart-tag-validation.yml",
|
|
152
|
+
"swift": ".github/workflows/swift-tag-validation.yml",
|
|
153
|
+
"kotlin": ".github/workflows/kotlin-tag-validation.yml",
|
|
154
|
+
"csharp": ".github/workflows/csharp-tag-validation.yml",
|
|
155
|
+
"c": ".github/workflows/c-tag-validation.yml",
|
|
156
|
+
"cpp": ".github/workflows/cpp-tag-validation.yml",
|
|
157
|
+
"shell": ".github/workflows/shell-tag-validation.yml",
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if language.lower() not in workflow_mapping:
|
|
161
|
+
raise ValueError(
|
|
162
|
+
f"Unsupported language: {language}. "
|
|
163
|
+
f"Supported languages: {', '.join(workflow_mapping.keys())}"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return workflow_mapping[language.lower()]
|
|
167
|
+
|
|
168
|
+
def detect_package_manager(self, path: str | Path = ".") -> str | None:
|
|
169
|
+
"""Detect the package manager for the detected language.
|
|
170
|
+
|
|
171
|
+
@CODE:LDE-PKG-MGR-001 | SPEC: SPEC-LANGUAGE-DETECTION-EXTENDED-001/spec.md
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
path: Directory to inspect.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Package manager name or None if not detected.
|
|
178
|
+
"""
|
|
179
|
+
path = Path(path)
|
|
180
|
+
|
|
181
|
+
# Ruby
|
|
182
|
+
if (path / "Gemfile").exists():
|
|
183
|
+
return "bundle"
|
|
184
|
+
|
|
185
|
+
# PHP
|
|
186
|
+
if (path / "composer.json").exists():
|
|
187
|
+
return "composer"
|
|
188
|
+
|
|
189
|
+
# Java/Kotlin
|
|
190
|
+
if (path / "pom.xml").exists():
|
|
191
|
+
return "maven"
|
|
192
|
+
if (path / "build.gradle").exists() or (path / "build.gradle.kts").exists():
|
|
193
|
+
return "gradle"
|
|
194
|
+
|
|
195
|
+
# Rust
|
|
196
|
+
if (path / "Cargo.toml").exists():
|
|
197
|
+
return "cargo"
|
|
198
|
+
|
|
199
|
+
# Dart/Flutter
|
|
200
|
+
if (path / "pubspec.yaml").exists():
|
|
201
|
+
return "dart_pub"
|
|
202
|
+
|
|
203
|
+
# Swift
|
|
204
|
+
if (path / "Package.swift").exists():
|
|
205
|
+
return "spm"
|
|
206
|
+
|
|
207
|
+
# C#
|
|
208
|
+
if list(path.glob("*.csproj")) or list(path.glob("*.sln")):
|
|
209
|
+
return "dotnet"
|
|
210
|
+
|
|
211
|
+
# Python
|
|
212
|
+
if (path / "pyproject.toml").exists():
|
|
213
|
+
return "pip"
|
|
214
|
+
|
|
215
|
+
# JavaScript/TypeScript (check in priority order)
|
|
216
|
+
# Check for lock files and package managers
|
|
217
|
+
if (path / "bun.lockb").exists():
|
|
218
|
+
return "bun"
|
|
219
|
+
elif (path / "pnpm-lock.yaml").exists():
|
|
220
|
+
return "pnpm"
|
|
221
|
+
elif (path / "yarn.lock").exists():
|
|
222
|
+
return "yarn"
|
|
223
|
+
elif (path / "package-lock.json").exists():
|
|
224
|
+
return "npm"
|
|
225
|
+
elif (path / "package.json").exists():
|
|
226
|
+
# Default to npm for package.json without lock files
|
|
227
|
+
return "npm"
|
|
228
|
+
|
|
229
|
+
# Go
|
|
230
|
+
if (path / "go.mod").exists():
|
|
231
|
+
return "go_modules"
|
|
232
|
+
|
|
233
|
+
return None
|
|
234
|
+
|
|
235
|
+
def detect_build_tool(self, path: str | Path = ".", language: str | None = None) -> str | None:
|
|
236
|
+
"""Detect the build tool for the detected language.
|
|
237
|
+
|
|
238
|
+
@CODE:LDE-BUILD-TOOL-001 | SPEC: SPEC-LANGUAGE-DETECTION-EXTENDED-001/spec.md
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
path: Directory to inspect.
|
|
242
|
+
language: Optional language hint for disambiguation.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
Build tool name or None if not detected.
|
|
246
|
+
"""
|
|
247
|
+
path = Path(path)
|
|
248
|
+
|
|
249
|
+
# C/C++
|
|
250
|
+
if (path / "CMakeLists.txt").exists():
|
|
251
|
+
return "cmake"
|
|
252
|
+
if (path / "Makefile").exists():
|
|
253
|
+
return "make"
|
|
254
|
+
|
|
255
|
+
# Java/Kotlin
|
|
256
|
+
if language in ["java", "kotlin"]:
|
|
257
|
+
if (path / "pom.xml").exists():
|
|
258
|
+
return "maven"
|
|
259
|
+
if (path / "build.gradle").exists() or (path / "build.gradle.kts").exists():
|
|
260
|
+
return "gradle"
|
|
261
|
+
|
|
262
|
+
# Rust
|
|
263
|
+
if (path / "Cargo.toml").exists():
|
|
264
|
+
return "cargo"
|
|
265
|
+
|
|
266
|
+
# Swift
|
|
267
|
+
if (path / "Package.swift").exists():
|
|
268
|
+
return "spm"
|
|
269
|
+
if list(path.glob("*.xcodeproj")) or list(path.glob("*.xcworkspace")):
|
|
270
|
+
return "xcode"
|
|
271
|
+
|
|
272
|
+
# C#
|
|
273
|
+
if list(path.glob("*.csproj")) or list(path.glob("*.sln")):
|
|
274
|
+
return "dotnet"
|
|
275
|
+
|
|
276
|
+
return None
|
|
277
|
+
|
|
278
|
+
def get_supported_languages_for_workflows(self) -> list[str]:
|
|
279
|
+
"""Get the list of languages with dedicated CI/CD workflow support.
|
|
280
|
+
|
|
281
|
+
@CODE:LDE-SUPPORTED-LANGS-001 | SPEC: SPEC-LANGUAGE-DETECTION-EXTENDED-001/spec.md
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
List of supported language names (15 total).
|
|
285
|
+
"""
|
|
286
|
+
return [
|
|
287
|
+
"python",
|
|
288
|
+
"javascript",
|
|
289
|
+
"typescript",
|
|
290
|
+
"go",
|
|
291
|
+
"ruby",
|
|
292
|
+
"php",
|
|
293
|
+
"java",
|
|
294
|
+
"rust",
|
|
295
|
+
"dart",
|
|
296
|
+
"swift",
|
|
297
|
+
"kotlin",
|
|
298
|
+
"csharp",
|
|
299
|
+
"c",
|
|
300
|
+
"cpp",
|
|
301
|
+
"shell",
|
|
302
|
+
]
|
|
303
|
+
|
|
115
304
|
|
|
116
305
|
def detect_project_language(path: str | Path = ".") -> str | None:
|
|
117
306
|
"""Detect the project language (helper).
|
|
@@ -11,7 +11,9 @@ Phase-based 5-step initialization process:
|
|
|
11
11
|
5. Validation: Verification and finalization
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
+
import json
|
|
14
15
|
import time
|
|
16
|
+
from datetime import datetime
|
|
15
17
|
from pathlib import Path
|
|
16
18
|
|
|
17
19
|
from moai_adk.core.project.phase_executor import PhaseExecutor, ProgressCallback
|
|
@@ -55,6 +57,62 @@ class ProjectInitializer:
|
|
|
55
57
|
self.validator = ProjectValidator()
|
|
56
58
|
self.executor = PhaseExecutor(self.validator)
|
|
57
59
|
|
|
60
|
+
def _create_memory_files(self) -> list[str]:
|
|
61
|
+
"""Create runtime session and memory files (auto-generated per user/session)
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
List of created memory files
|
|
65
|
+
|
|
66
|
+
@CODE:INIT-MEMORY-001 | Auto-generate session memory files
|
|
67
|
+
"""
|
|
68
|
+
memory_dir = self.path / ".moai" / "memory"
|
|
69
|
+
memory_dir.mkdir(parents=True, exist_ok=True)
|
|
70
|
+
created_files = []
|
|
71
|
+
|
|
72
|
+
# 1. project-notes.json - Project tracking notes (empty on init)
|
|
73
|
+
project_notes = {
|
|
74
|
+
"tech_debt": [],
|
|
75
|
+
"performance_bottlenecks": [],
|
|
76
|
+
"recent_patterns": {
|
|
77
|
+
"frequent_file_edits": [],
|
|
78
|
+
"test_failures": [],
|
|
79
|
+
"git_operations": "daily commits, feature branches"
|
|
80
|
+
},
|
|
81
|
+
"next_priorities": []
|
|
82
|
+
}
|
|
83
|
+
project_notes_file = memory_dir / "project-notes.json"
|
|
84
|
+
project_notes_file.write_text(json.dumps(project_notes, indent=2))
|
|
85
|
+
created_files.append(str(project_notes_file))
|
|
86
|
+
|
|
87
|
+
# 2. session-hint.json - Last session state
|
|
88
|
+
session_hint = {
|
|
89
|
+
"last_command": None,
|
|
90
|
+
"command_timestamp": None,
|
|
91
|
+
"hours_ago": None,
|
|
92
|
+
"active_spec": None,
|
|
93
|
+
"current_branch": "main"
|
|
94
|
+
}
|
|
95
|
+
session_hint_file = memory_dir / "session-hint.json"
|
|
96
|
+
session_hint_file.write_text(json.dumps(session_hint, indent=2))
|
|
97
|
+
created_files.append(str(session_hint_file))
|
|
98
|
+
|
|
99
|
+
# 3. user-patterns.json - User preferences and expertise
|
|
100
|
+
user_patterns = {
|
|
101
|
+
"tech_preferences": {},
|
|
102
|
+
"expertise_signals": {
|
|
103
|
+
"ask_question_skip_rate": 0.0,
|
|
104
|
+
"custom_workflows": 0,
|
|
105
|
+
"estimated_level": "beginner"
|
|
106
|
+
},
|
|
107
|
+
"skip_questions": [],
|
|
108
|
+
"last_updated": datetime.now().isoformat() + "Z"
|
|
109
|
+
}
|
|
110
|
+
user_patterns_file = memory_dir / "user-patterns.json"
|
|
111
|
+
user_patterns_file.write_text(json.dumps(user_patterns, indent=2))
|
|
112
|
+
created_files.append(str(user_patterns_file))
|
|
113
|
+
|
|
114
|
+
return created_files
|
|
115
|
+
|
|
58
116
|
def initialize(
|
|
59
117
|
self,
|
|
60
118
|
mode: str = "personal",
|
|
@@ -144,6 +202,9 @@ class ProjectInitializer:
|
|
|
144
202
|
self.path, mode, progress_callback
|
|
145
203
|
)
|
|
146
204
|
|
|
205
|
+
# Phase 6: Create runtime memory files (auto-generated per user/session)
|
|
206
|
+
memory_files = self._create_memory_files()
|
|
207
|
+
|
|
147
208
|
# Generate result
|
|
148
209
|
duration = int((time.time() - start_time) * 1000) # ms
|
|
149
210
|
return InstallationResult(
|
|
@@ -153,7 +214,7 @@ class ProjectInitializer:
|
|
|
153
214
|
mode=mode,
|
|
154
215
|
locale=locale,
|
|
155
216
|
duration=duration,
|
|
156
|
-
created_files=resource_files + config_files,
|
|
217
|
+
created_files=resource_files + config_files + memory_files,
|
|
157
218
|
)
|
|
158
219
|
|
|
159
220
|
except Exception as e:
|