kimi-dev-workflow 0.1.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.
Files changed (31) hide show
  1. kimi_dev_workflow/__init__.py +3 -0
  2. kimi_dev_workflow/cli.py +45 -0
  3. kimi_dev_workflow/commands/__init__.py +1 -0
  4. kimi_dev_workflow/commands/doctor.py +119 -0
  5. kimi_dev_workflow/commands/index.py +84 -0
  6. kimi_dev_workflow/commands/init.py +242 -0
  7. kimi_dev_workflow/commands/memory.py +47 -0
  8. kimi_dev_workflow/commands/wiki.py +75 -0
  9. kimi_dev_workflow/config.py +52 -0
  10. kimi_dev_workflow/detector.py +130 -0
  11. kimi_dev_workflow/renderer.py +107 -0
  12. kimi_dev_workflow/scripts/kimi-index +231 -0
  13. kimi_dev_workflow/scripts/kimi-wiki +294 -0
  14. kimi_dev_workflow/scripts/release.sh +71 -0
  15. kimi_dev_workflow/templates/.grepaiignore.template +97 -0
  16. kimi_dev_workflow/templates/AGENTS.md.template +109 -0
  17. kimi_dev_workflow/templates/kimi_dir/README.md +144 -0
  18. kimi_dev_workflow/templates/kimi_dir/memory.md.template +53 -0
  19. kimi_dev_workflow/templates/kimi_dir/prompts/01-search.md +24 -0
  20. kimi_dev_workflow/templates/kimi_dir/prompts/02-code.md +33 -0
  21. kimi_dev_workflow/templates/kimi_dir/prompts/03-refactor.md +29 -0
  22. kimi_dev_workflow/templates/kimi_dir/prompts/04-debug.md +34 -0
  23. kimi_dev_workflow/templates/kimi_dir/prompts/05-review.md +31 -0
  24. kimi_dev_workflow/templates/kimi_dir/prompts/06-wiki.md +22 -0
  25. kimi_dev_workflow/templates/kimi_dir/prompts/07-memory.md +32 -0
  26. kimi_dev_workflow/utils.py +43 -0
  27. kimi_dev_workflow-0.1.0.dist-info/METADATA +317 -0
  28. kimi_dev_workflow-0.1.0.dist-info/RECORD +31 -0
  29. kimi_dev_workflow-0.1.0.dist-info/WHEEL +4 -0
  30. kimi_dev_workflow-0.1.0.dist-info/entry_points.txt +2 -0
  31. kimi_dev_workflow-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,3 @@
1
+ """Kimi Dev Workflow — 让 Kimi CLI 像 Cursor 一样理解你的代码库."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,45 @@
1
+ """Kimi Dev Workflow — Unified CLI entry point."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import click
6
+
7
+ from .commands import doctor, index, init, memory, wiki
8
+ from .config import __version__
9
+
10
+
11
+ @click.group(
12
+ context_settings={"help_option_names": ["-h", "--help"]},
13
+ invoke_without_command=True,
14
+ )
15
+ @click.version_option(version=__version__, prog_name="kimi-dev")
16
+ @click.pass_context
17
+ def main(ctx: click.Context) -> None:
18
+ """Kimi Dev Workflow — 让 Kimi CLI 像 Cursor 一样理解你的代码库.
19
+
20
+ \b
21
+ 快速开始:
22
+ cd your-project
23
+ kimi-dev init
24
+ kimi-dev index start
25
+ """
26
+ if ctx.invoked_subcommand is None:
27
+ click.echo(ctx.get_help())
28
+
29
+
30
+ # Register commands
31
+ main.add_command(init.init)
32
+ main.add_command(index.index)
33
+ main.add_command(wiki.wiki)
34
+ main.add_command(memory.memory)
35
+ main.add_command(doctor.doctor)
36
+
37
+ # Add version as a top-level command too
38
+ @main.command("version")
39
+ def version_cmd() -> None:
40
+ """显示版本号."""
41
+ click.echo(f"kimi-dev {__version__}")
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()
@@ -0,0 +1 @@
1
+ """Kimi Dev Workflow CLI commands."""
@@ -0,0 +1,119 @@
1
+ """kimi-dev doctor — Environment diagnostics."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import shutil
6
+ import subprocess
7
+ from urllib.request import urlopen
8
+
9
+ import click
10
+ from rich.console import Console
11
+ from rich.table import Table
12
+
13
+ from ..config import OLLAMA_HOST
14
+
15
+ console = Console()
16
+
17
+
18
+ def _check_cmd(name: str) -> tuple[bool, str]:
19
+ """Check if a command exists and get its version."""
20
+ path = shutil.which(name)
21
+ if not path:
22
+ return False, "未安装"
23
+
24
+ version = "未知版本"
25
+ for flag in ["--version", "-v", "version"]:
26
+ try:
27
+ result = subprocess.run(
28
+ [name, flag],
29
+ capture_output=True,
30
+ text=True,
31
+ timeout=5,
32
+ )
33
+ if result.returncode == 0:
34
+ output = (result.stdout + result.stderr).strip().splitlines()[0]
35
+ version = output[:60]
36
+ break
37
+ except (subprocess.TimeoutExpired, Exception):
38
+ continue
39
+
40
+ return True, version
41
+
42
+
43
+ def _check_ollama() -> tuple[bool, str]:
44
+ """Check if Ollama is running."""
45
+ try:
46
+ with urlopen(f"{OLLAMA_HOST}/api/tags", timeout=3) as resp:
47
+ if resp.status == 200:
48
+ return True, "运行中"
49
+ except Exception:
50
+ pass
51
+ return False, "未运行"
52
+
53
+
54
+ @click.command()
55
+ def doctor() -> None:
56
+ """诊断环境依赖状态.
57
+
58
+ 检查 kimi、grepai、ollama 等必要依赖是否安装并正常运行。
59
+ """
60
+ console.print("")
61
+ console.print("[bold blue]🔍 环境诊断[/bold blue]")
62
+ console.print("")
63
+
64
+ table = Table(show_header=True, header_style="bold")
65
+ table.add_column("依赖")
66
+ table.add_column("状态")
67
+ table.add_column("版本/信息")
68
+
69
+ # Kimi CLI
70
+ ok, info = _check_cmd("kimi")
71
+ status = "[green]✓[/green]" if ok else "[red]✗[/red]"
72
+ table.add_row("Kimi CLI", status, info)
73
+
74
+ # grepai
75
+ ok, info = _check_cmd("grepai")
76
+ status = "[green]✓[/green]" if ok else "[red]✗[/red]"
77
+ table.add_row("grepai", status, info)
78
+
79
+ # Ollama service
80
+ ok, info = _check_ollama()
81
+ status = "[green]✓[/green]" if ok else "[red]✗[/red]"
82
+ table.add_row("Ollama", status, info)
83
+
84
+ # ollama binary
85
+ ok, info = _check_cmd("ollama")
86
+ status = "[green]✓[/green]" if ok else "[red]✗[/red]"
87
+ table.add_row("ollama CLI", status, info)
88
+
89
+ # git
90
+ ok, info = _check_cmd("git")
91
+ status = "[green]✓[/green]" if ok else "[red]✗[/red]"
92
+ table.add_row("git", status, info)
93
+
94
+ # Python
95
+ ok, info = _check_cmd("python3")
96
+ if not ok:
97
+ ok, info = _check_cmd("python")
98
+ status = "[green]✓[/green]" if ok else "[red]✗[/red]"
99
+ table.add_row("Python", status, info)
100
+
101
+ console.print(table)
102
+ console.print("")
103
+
104
+ # Recommendations
105
+ has_issues = False
106
+ if not shutil.which("kimi"):
107
+ console.print("[yellow]💡 Kimi CLI 未安装:[/yellow] curl -fsSL https://cli.moonshot.cn/install.sh | sh")
108
+ has_issues = True
109
+ if not shutil.which("grepai"):
110
+ console.print("[yellow]💡 grepai 未安装:[/yellow] curl -fsSL https://raw.githubusercontent.com/yoanbernabeu/grepai/main/install.sh | INSTALL_DIR=$HOME/.local/bin sh")
111
+ has_issues = True
112
+ if not _check_ollama()[0]:
113
+ console.print("[yellow]💡 Ollama 未运行:[/yellow] https://ollama.com/download")
114
+ has_issues = True
115
+
116
+ if not has_issues:
117
+ console.print("[bold green]✅ 所有依赖已就绪![/bold green]")
118
+
119
+ console.print("")
@@ -0,0 +1,84 @@
1
+ """kimi-dev index — Code index management commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+
7
+ import click
8
+ from rich.console import Console
9
+
10
+ from ..config import GREPAI_BIN
11
+ from ..utils import find_script
12
+
13
+ console = Console()
14
+
15
+
16
+ def _run_kimi_index_cmd(args: list[str]) -> None:
17
+ """Run kimi-index script, finding it in various locations."""
18
+ script = find_script("kimi-index")
19
+ if script:
20
+ subprocess.run([script] + args, check=False)
21
+ else:
22
+ console.print("[red]✗[/red] kimi-index 未找到。请确保 kimi-dev-workflow 正确安装。")
23
+
24
+
25
+ @click.group("index", help="代码索引管理")
26
+ def index() -> None:
27
+ """管理本地代码语义索引."""
28
+ pass
29
+
30
+
31
+ @index.command("start")
32
+ def start() -> None:
33
+ """启动索引监听(后台运行)."""
34
+ console.print("[blue]ℹ[/blue] 启动代码索引...")
35
+ _run_kimi_index_cmd(["start"])
36
+
37
+
38
+ @index.command("stop")
39
+ def stop() -> None:
40
+ """停止索引监听."""
41
+ _run_kimi_index_cmd(["stop"])
42
+
43
+
44
+ @index.command("status")
45
+ def status() -> None:
46
+ """查看索引状态."""
47
+ _run_kimi_index_cmd(["status"])
48
+
49
+
50
+ @index.command("search")
51
+ @click.argument("query", nargs=-1, required=True)
52
+ def search(query: tuple[str, ...]) -> None:
53
+ """语义搜索代码库.
54
+
55
+ \b
56
+ 示例:
57
+ kimi-dev index search "用户认证逻辑"
58
+ kimi-dev index search "JWT token 刷新"
59
+ """
60
+ q = " ".join(query)
61
+ script = find_script("kimi-index")
62
+ if script:
63
+ subprocess.run([script, "search", q], check=False)
64
+ else:
65
+ # Fallback to direct grepai
66
+ try:
67
+ subprocess.run([GREPAI_BIN, "search", q], check=False)
68
+ except FileNotFoundError:
69
+ console.print("[red]✗[/red] grepai 未安装。")
70
+
71
+
72
+ @index.command("reindex")
73
+ def reindex() -> None:
74
+ """重置并重新索引."""
75
+ if not click.confirm("确定要重置并重新索引吗? 这将删除现有索引数据。", default=False):
76
+ console.print("[yellow]已取消[/yellow]")
77
+ return
78
+ _run_kimi_index_cmd(["reindex"])
79
+
80
+
81
+ @index.command("logs")
82
+ def logs() -> None:
83
+ """查看索引日志."""
84
+ _run_kimi_index_cmd(["logs"])
@@ -0,0 +1,242 @@
1
+ """kimi-dev init — Initialize a project with kimi-dev-workflow templates."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib.resources as pkg_resources
6
+ import shutil
7
+ import subprocess
8
+ from pathlib import Path
9
+
10
+ import click
11
+ from rich.console import Console
12
+
13
+ from ..config import (
14
+ AGENTS_FILE,
15
+ GREPAIIGNORE_FILE,
16
+ INDEX_DIR,
17
+ KIMI_DIR,
18
+ MEMORY_FILE,
19
+ PACKAGE_NAME,
20
+ WIKI_DIR,
21
+ )
22
+ from ..detector import detect_project, detect_project_name
23
+ from ..renderer import write_agents
24
+
25
+ console = Console()
26
+
27
+
28
+ def _get_resource_path(module: str, filename: str) -> Path:
29
+ """Get a resource file path from the package."""
30
+ try:
31
+ return Path(str(pkg_resources.files(module).joinpath(filename)))
32
+ except (AttributeError, TypeError):
33
+ with pkg_resources.path(module, filename) as p:
34
+ return Path(str(p))
35
+
36
+
37
+ def _copy_template(src_module: str, src_name: str, dst: Path) -> None:
38
+ """Copy a template file from package resources to destination."""
39
+ src = _get_resource_path(src_module, src_name)
40
+ dst.parent.mkdir(parents=True, exist_ok=True)
41
+ shutil.copy2(src, dst)
42
+
43
+
44
+ def _copy_directory(src_module: str, dst: Path) -> None:
45
+ """Copy all files from a package resource directory."""
46
+ try:
47
+ files = pkg_resources.files(src_module)
48
+ for item in files.iterdir():
49
+ if item.is_file():
50
+ dst.parent.mkdir(parents=True, exist_ok=True)
51
+ shutil.copy2(str(item), dst.parent / item.name)
52
+ elif item.is_dir():
53
+ sub_dst = dst / item.name
54
+ sub_dst.mkdir(parents=True, exist_ok=True)
55
+ _copy_directory(f"{src_module}.{item.name}", sub_dst)
56
+ except (AttributeError, TypeError):
57
+ # Fallback: try to use path directly
58
+ with pkg_resources.path(src_module, "") as p:
59
+ src_path = Path(str(p))
60
+ if src_path.exists():
61
+ for item in src_path.iterdir():
62
+ if item.is_file():
63
+ dst.parent.mkdir(parents=True, exist_ok=True)
64
+ shutil.copy2(item, dst.parent / item.name)
65
+ elif item.is_dir() and not item.name.startswith("__"):
66
+ sub_dst = dst / item.name
67
+ shutil.copytree(item, sub_dst, dirs_exist_ok=True)
68
+
69
+
70
+ @click.command()
71
+ @click.option(
72
+ "--wiki-url",
73
+ help="从远程克隆 Wiki 仓库地址",
74
+ )
75
+ @click.option(
76
+ "--project-type",
77
+ type=click.Choice(["react", "vue", "go", "python", "rust", "node", "unknown"]),
78
+ help="强制指定项目类型(自动检测失败时使用)",
79
+ )
80
+ @click.option(
81
+ "--yes / -y",
82
+ "non_interactive",
83
+ default=False,
84
+ help="跳过交互确认,自动填充默认值",
85
+ )
86
+ @click.option(
87
+ "--no-wiki",
88
+ is_flag=True,
89
+ default=False,
90
+ help="不初始化 Wiki 目录",
91
+ )
92
+ @click.pass_context
93
+ def init(
94
+ ctx: click.Context,
95
+ wiki_url: str | None,
96
+ project_type: str | None,
97
+ non_interactive: bool,
98
+ no_wiki: bool,
99
+ ) -> None:
100
+ """初始化当前项目,自动复制模板并配置环境.
101
+
102
+ \b
103
+ 示例:
104
+ kimi-dev init
105
+ kimi-dev init --wiki-url https://github.com/user/repo.wiki.git
106
+ kimi-dev init --yes
107
+ """
108
+ cwd = Path.cwd()
109
+
110
+ console.print("")
111
+ console.print("[bold blue]🚀 Kimi Dev Workflow 项目初始化[/bold blue]")
112
+ console.print("")
113
+
114
+ # 1. Detect project type
115
+ info = detect_project(cwd)
116
+ if project_type:
117
+ # Override if explicitly specified
118
+ from ..detector import ProjectInfo
119
+ info = ProjectInfo(project_type, info.framework, info.language, info.build_tool)
120
+
121
+ project_name = detect_project_name(cwd)
122
+
123
+ type_display = f"{info.framework} + {info.language}" if info.framework != info.language else info.framework
124
+ console.print(f"[blue]ℹ[/blue] 检测到项目类型: [bold]{type_display}[/bold]")
125
+ console.print(f"[blue]ℹ[/blue] 项目名称: [bold]{project_name}[/bold]")
126
+ console.print("")
127
+
128
+ if not non_interactive:
129
+ if not click.confirm("是否继续初始化?", default=True):
130
+ console.print("[yellow]已取消[/yellow]")
131
+ return
132
+
133
+ # 2. Generate AGENTS.md
134
+ agents_path = cwd / AGENTS_FILE
135
+ if agents_path.exists():
136
+ backup = agents_path.with_suffix(".md.backup")
137
+ shutil.copy2(agents_path, backup)
138
+ console.print(f"[yellow]⚠[/yellow] AGENTS.md 已存在,已备份到 {backup.name}")
139
+
140
+ write_agents(cwd, info, project_name)
141
+ console.print(f"[green]✓[/green] 已生成 {AGENTS_FILE}")
142
+
143
+ if not non_interactive:
144
+ console.print("[yellow]⚠[/yellow] 请检查 AGENTS.md 中的内容并根据项目实际情况修改")
145
+
146
+ # 3. Copy .kimi/ directory
147
+ kimi_dst = cwd / KIMI_DIR
148
+ kimi_src_module = f"{PACKAGE_NAME}.templates.kimi_dir"
149
+
150
+ # Copy memory.md.template
151
+ memory_template = _get_resource_path(kimi_src_module, "memory.md.template")
152
+ memory_dst = cwd / MEMORY_FILE
153
+ memory_dst.parent.mkdir(parents=True, exist_ok=True)
154
+ shutil.copy2(memory_template, memory_dst)
155
+ console.print(f"[green]✓[/green] 已创建 {MEMORY_FILE}")
156
+
157
+ # Copy prompts
158
+ prompts_src = f"{kimi_src_module}.prompts"
159
+ prompts_dst = cwd / KIMI_DIR / "prompts"
160
+ try:
161
+ pkg = pkg_resources.files(prompts_src)
162
+ prompts_dst.mkdir(parents=True, exist_ok=True)
163
+ for item in pkg.iterdir():
164
+ if item.is_file() and item.name.endswith(".md"):
165
+ shutil.copy2(str(item), prompts_dst / item.name)
166
+ except (AttributeError, TypeError):
167
+ with pkg_resources.path(prompts_src, "") as p:
168
+ src_path = Path(str(p))
169
+ if src_path.exists():
170
+ prompts_dst.mkdir(parents=True, exist_ok=True)
171
+ for f in src_path.glob("*.md"):
172
+ shutil.copy2(f, prompts_dst / f.name)
173
+
174
+ # Copy .kimi/README.md
175
+ readme_src = _get_resource_path(kimi_src_module, "README.md")
176
+ readme_dst = cwd / KIMI_DIR / "README.md"
177
+ shutil.copy2(readme_src, readme_dst)
178
+ console.print(f"[green]✓[/green] 已复制 prompt 模板到 {KIMI_DIR}/prompts/")
179
+
180
+ # 4. Copy .grepaiignore
181
+ grepaiignore_src = _get_resource_path(f"{PACKAGE_NAME}.templates", GREPAIIGNORE_FILE + ".template")
182
+ grepaiignore_dst = cwd / GREPAIIGNORE_FILE
183
+ shutil.copy2(grepaiignore_src, grepaiignore_dst)
184
+ console.print(f"[green]✓[/green] 已创建 {GREPAIIGNORE_FILE}")
185
+
186
+ # 5. Initialize wiki
187
+ if not no_wiki:
188
+ wiki_path = cwd / WIKI_DIR
189
+ if not wiki_path.exists():
190
+ wiki_path.mkdir(parents=True, exist_ok=True)
191
+ # Create example pages
192
+ (wiki_path / "01-getting-started.md").write_text(
193
+ "# 项目入门指南\n\n## 环境搭建\n\n## 快速开始\n\n## 常用命令\n",
194
+ encoding="utf-8",
195
+ )
196
+ (wiki_path / "02-architecture.md").write_text(
197
+ "# 架构说明\n\n## 系统架构图\n\n## 模块划分\n\n## 技术选型理由\n",
198
+ encoding="utf-8",
199
+ )
200
+ console.print(f"[green]✓[/green] 已创建 {WIKI_DIR}/ 目录及示例页面")
201
+
202
+ if wiki_url:
203
+ console.print(f"[blue]ℹ[/blue] 正在克隆远程 Wiki: {wiki_url}")
204
+ try:
205
+ if wiki_path.exists() and any(wiki_path.iterdir()):
206
+ backup = cwd / f"{WIKI_DIR}.backup"
207
+ shutil.move(str(wiki_path), str(backup))
208
+ console.print(f"[yellow]⚠[/yellow] 已备份旧 wiki 到 {backup.name}")
209
+ subprocess.run(["git", "clone", wiki_url, str(wiki_path)], check=True, capture_output=True)
210
+ (wiki_path / ".wiki-origin").write_text(wiki_url + "\n", encoding="utf-8")
211
+ console.print(f"[green]✓[/green] Wiki 克隆成功")
212
+ except subprocess.CalledProcessError:
213
+ console.print(f"[red]✗[/red] Wiki 克隆失败,请检查仓库地址")
214
+
215
+ # 6. Initialize grepai
216
+ if not (cwd / INDEX_DIR).exists():
217
+ try:
218
+ result = subprocess.run(
219
+ ["grepai", "init"],
220
+ capture_output=True,
221
+ text=True,
222
+ cwd=cwd,
223
+ )
224
+ if result.returncode == 0:
225
+ console.print(f"[green]✓[/green] 已初始化 {INDEX_DIR}/")
226
+ else:
227
+ console.print(f"[yellow]⚠[/yellow] grepai init 输出: {result.stderr.strip() or result.stdout.strip()}")
228
+ except FileNotFoundError:
229
+ console.print(f"[yellow]⚠[/yellow] grepai 未安装,跳过索引初始化")
230
+ console.print(" 安装: curl -fsSL https://raw.githubusercontent.com/yoanbernabeu/grepai/main/install.sh | INSTALL_DIR=$HOME/.local/bin sh")
231
+ else:
232
+ console.print(f"[blue]ℹ[/blue] {INDEX_DIR}/ 已存在,跳过初始化")
233
+
234
+ # 7. Summary
235
+ console.print("")
236
+ console.print("[bold green]✅ 初始化完成![/bold green]")
237
+ console.print("")
238
+ console.print("[bold]下一步:[/bold]")
239
+ console.print(" 1. 编辑 AGENTS.md 完善项目信息")
240
+ console.print(" 2. 运行 [bold]kimi-dev index start[/bold] 启动索引")
241
+ console.print(" 3. 运行 [bold]kimi[/bold] 开始开发")
242
+ console.print("")
@@ -0,0 +1,47 @@
1
+ """kimi-dev memory — Agent memory commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import click
8
+ from rich.console import Console
9
+
10
+ from ..config import MEMORY_FILE
11
+
12
+ console = Console()
13
+
14
+
15
+ @click.group("memory", help="Agent 记忆管理")
16
+ def memory() -> None:
17
+ """查看和管理 Agent 记忆文件."""
18
+ pass
19
+
20
+
21
+ @memory.command("show")
22
+ def show() -> None:
23
+ """查看记忆文件内容."""
24
+ path = Path.cwd() / MEMORY_FILE
25
+ if not path.exists():
26
+ console.print(f"[yellow]⚠[/yellow] 记忆文件不存在: {MEMORY_FILE}")
27
+ console.print(" 运行 [bold]kimi-dev init[/bold] 创建")
28
+ return
29
+
30
+ content = path.read_text(encoding="utf-8")
31
+ console.print(f"[bold blue]{MEMORY_FILE}[/bold blue]")
32
+ console.print("")
33
+ console.print(content)
34
+
35
+
36
+ @memory.command("edit")
37
+ def edit() -> None:
38
+ """用默认编辑器打开记忆文件."""
39
+ path = Path.cwd() / MEMORY_FILE
40
+ if not path.exists():
41
+ console.print(f"[yellow]⚠[/yellow] 记忆文件不存在: {MEMORY_FILE}")
42
+ return
43
+
44
+ import os
45
+
46
+ editor = os.environ.get("EDITOR", "vim")
47
+ click.launch(str(path), wait=True, locate=False)
@@ -0,0 +1,75 @@
1
+ """kimi-dev wiki — Repo Wiki management commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+
7
+ import click
8
+ from rich.console import Console
9
+
10
+ from ..utils import find_script
11
+
12
+ console = Console()
13
+
14
+
15
+ def _run_kimi_wiki_cmd(args: list[str]) -> None:
16
+ """Run kimi-wiki script, finding it in various locations."""
17
+ script = find_script("kimi-wiki")
18
+ if script:
19
+ subprocess.run([script] + args, check=False)
20
+ else:
21
+ console.print("[red]✗[/red] kimi-wiki 未找到。请确保 kimi-dev-workflow 正确安装。")
22
+
23
+
24
+ @click.group("wiki", help="Repo Wiki 管理")
25
+ def wiki() -> None:
26
+ """管理项目 Wiki 知识库."""
27
+ pass
28
+
29
+
30
+ @wiki.command("init")
31
+ @click.argument("url", required=False)
32
+ def wiki_init(url: str | None) -> None:
33
+ """初始化 Wiki(本地或从远程克隆).
34
+
35
+ \b
36
+ 示例:
37
+ kimi-dev wiki init
38
+ kimi-dev wiki init https://github.com/user/repo.wiki.git
39
+ """
40
+ args = ["init"]
41
+ if url:
42
+ args.append(url)
43
+ _run_kimi_wiki_cmd(args)
44
+
45
+
46
+ @wiki.command("sync")
47
+ def wiki_sync() -> None:
48
+ """同步远程 Wiki 更新."""
49
+ _run_kimi_wiki_cmd(["sync"])
50
+
51
+
52
+ @wiki.command("list")
53
+ def wiki_list() -> None:
54
+ """列出所有 Wiki 页面."""
55
+ _run_kimi_wiki_cmd(["list"])
56
+
57
+
58
+ @wiki.command("search")
59
+ @click.argument("query", nargs=-1, required=True)
60
+ def wiki_search(query: tuple[str, ...]) -> None:
61
+ """语义搜索 Wiki 内容.
62
+
63
+ \b
64
+ 示例:
65
+ kimi-dev wiki search "订单状态机"
66
+ kimi-dev wiki search "API 约定"
67
+ """
68
+ q = " ".join(query)
69
+ _run_kimi_wiki_cmd(["search", q])
70
+
71
+
72
+ @wiki.command("status")
73
+ def wiki_status() -> None:
74
+ """查看 Wiki 状态."""
75
+ _run_kimi_wiki_cmd(["status"])
@@ -0,0 +1,52 @@
1
+ """Configuration constants for kimi-dev-workflow."""
2
+
3
+ import importlib.resources as pkg_resources
4
+ from pathlib import Path
5
+
6
+ __version__ = "0.1.0"
7
+
8
+ PACKAGE_NAME = "kimi_dev_workflow"
9
+
10
+ # Template paths (using importlib.resources for package-relative access)
11
+ TEMPLATES_MODULE = f"{PACKAGE_NAME}.templates"
12
+ KIMI_TEMPLATES_MODULE = f"{PACKAGE_NAME}.templates.kimi"
13
+
14
+ # Project-level paths
15
+ INDEX_DIR = ".grepai"
16
+ WIKI_DIR = "wiki"
17
+ MEMORY_FILE = ".kimi/memory.md"
18
+ AGENTS_FILE = "AGENTS.md"
19
+ GREPAIIGNORE_FILE = ".grepaiignore"
20
+ KIMI_DIR = ".kimi"
21
+
22
+ # External dependencies
23
+ OLLAMA_HOST = "http://localhost:11434"
24
+ GREPAI_BIN = "grepai"
25
+
26
+ # Supported project types
27
+ PROJECT_TYPES = ["react", "vue", "go", "python", "rust", "node", "unknown"]
28
+
29
+ # AGENTS.md template placeholders
30
+ AGENTS_PLACEHOLDERS = [
31
+ "{项目名}",
32
+ "{React/Vue/Svelte}",
33
+ "{版本}",
34
+ "{TypeScript/JavaScript}",
35
+ "{Vite/Webpack/Rollup}",
36
+ "{Zustand/Redux/Pinia}",
37
+ "{React Router/Vue Router/TanStack Router}",
38
+ "{Tailwind/Styled Components/SCSS/Less}",
39
+ "{Axios/Fetch/TanStack Query}",
40
+ "{Zod/Yup/Joi}",
41
+ "{react-hook-form/VeeValidate}",
42
+ "{store}",
43
+ "{Context/useState}",
44
+ "{ErrorClass}",
45
+ "{校验库}",
46
+ "{路由文件路径}",
47
+ "{store 目录路径}",
48
+ "{API 封装路径}",
49
+ "{认证相关文件}",
50
+ "{布局组件路径}",
51
+ "{路由文件}",
52
+ ]