feat: initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# AI IDE Configurators
|
||||
|
||||
ONW 5.0 组件:Cursor/Windsurf AI IDE 直接挂载适配器
|
||||
|
||||
本目录包含与主流 AI IDE 集成的适配器,实现:
|
||||
- 项目上下文自动注入
|
||||
- 代码生成规则同步
|
||||
- RAG 检索结果直接挂载
|
||||
- Genesis Contract IDE 层强制执行
|
||||
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
Cursor IDE Adapter
|
||||
NovelMaster Core Engine - Configurators
|
||||
|
||||
为 Cursor IDE 生成 .cursorrules 和项目配置
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional
|
||||
import json
|
||||
|
||||
|
||||
def generate_cursorrules_content(project_config: Dict[str, Any]) -> str:
|
||||
"""生成 .cursorrules 文件内容"""
|
||||
|
||||
genesis = project_config.get("genesis_contract", {})
|
||||
|
||||
rules = f"""# NovelMaster Cursor Rules
|
||||
|
||||
## 项目概览
|
||||
- 项目名称: {project_config.get("project_name", "未命名")}
|
||||
- 类型: {project_config.get("genre", "网文")}
|
||||
- 目标字数: {project_config.get("target_word_count", "未知")} 字
|
||||
|
||||
## 核心设定 (Genesis Contract)
|
||||
### 核心欲望
|
||||
{_format_dict(genesis.get("core_desire", {}))}
|
||||
|
||||
### 伦理沙盒
|
||||
{_format_dict(genesis.get("ethical_inversion", {}))}
|
||||
|
||||
### 奇观日常化
|
||||
{_format_dict(genesis.get("core_spectacle", {}))}
|
||||
|
||||
## 写作规范
|
||||
- 使用中文思维写作
|
||||
- 章节字数: 2000-2500 字
|
||||
- 优先使用第三人称
|
||||
- 爽点密度: 每1000字至少1个情感释放点
|
||||
- 追读力 (Reading Power): 监控 Hook/Cool-point 平衡
|
||||
|
||||
## 状态管理
|
||||
- 数据目录: .noma/
|
||||
- 使用 handoff.py 进行帧交接
|
||||
- 使用 ledger.py 管理资产/负债
|
||||
- 使用 retcon_manager.py 处理设定修改
|
||||
|
||||
## 敏感内容
|
||||
- 禁止: 政治敏感、真实暴力、未成年人性内容
|
||||
- 伦理沙盒内创作自由
|
||||
"""
|
||||
|
||||
return rules
|
||||
|
||||
|
||||
def _format_dict(d: Dict[str, Any], indent: int = 2) -> str:
|
||||
if not d:
|
||||
return " (未设置)"
|
||||
lines = []
|
||||
for key, value in d.items():
|
||||
if isinstance(value, dict):
|
||||
lines.append(f" {key}:")
|
||||
lines.append(_format_dict(value, indent + 2))
|
||||
elif isinstance(value, list):
|
||||
lines.append(f" {key}: {', '.join(str(v) for v in value)}")
|
||||
else:
|
||||
lines.append(f" {key}: {value}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def generate_project_config(project_root: Path, config: Dict[str, Any]) -> Path:
|
||||
"""生成 Cursor 项目配置文件"""
|
||||
config_dir = project_root / ".cursor"
|
||||
config_dir.mkdir(exist_ok=True)
|
||||
|
||||
config_file = config_dir / "novelmaster.json"
|
||||
with open(config_file, "w", encoding="utf-8") as f:
|
||||
json.dump(config, f, ensure_ascii=False, indent=2)
|
||||
|
||||
rules_file = project_root / ".cursorrules"
|
||||
rules_content = generate_cursorrules_content(config)
|
||||
with open(rules_file, "w", encoding="utf-8") as f:
|
||||
f.write(rules_content)
|
||||
|
||||
return rules_file
|
||||
|
||||
|
||||
def detect_cursor_environment() -> bool:
|
||||
"""检测是否在 Cursor 环境中"""
|
||||
cursor_markers = [
|
||||
".cursor",
|
||||
".cursorrules",
|
||||
"cursor_rules",
|
||||
]
|
||||
for marker in cursor_markers:
|
||||
if Path(marker).exists():
|
||||
return True
|
||||
return False
|
||||
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
Universal IDE Adapter
|
||||
NovelMaster Core Engine - Configurators
|
||||
|
||||
跨IDE统一接口 (Cursor, Windsurf, VS Code, JetBrains)
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional, List
|
||||
from enum import Enum
|
||||
|
||||
from .cursor_adapter import generate_project_config as cursor_generate
|
||||
from .windsurf_adapter import setup_windsurf
|
||||
|
||||
|
||||
class IDEType(Enum):
|
||||
CURSOR = "cursor"
|
||||
WINDSURF = "windsurf"
|
||||
VSCODE = "vscode"
|
||||
JETBRAINS = "jetbrains"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
def detect_ide() -> IDEType:
|
||||
"""检测当前 IDE 环境"""
|
||||
markers = Path.cwd()
|
||||
|
||||
cursor_markers = [".cursorrules", ".cursor"]
|
||||
windsurf_markers = [".windsurfrules", ".windsurf"]
|
||||
|
||||
for marker in cursor_markers:
|
||||
if (markers / marker).exists():
|
||||
return IDEType.CURSOR
|
||||
|
||||
for marker in windsurf_markers:
|
||||
if (markers / marker).exists():
|
||||
return IDEType.WINDSURF
|
||||
|
||||
if "cursor" in Path.cwd().parts or "cursor" in str(Path(__file__)):
|
||||
return IDEType.CURSOR
|
||||
elif "windsurf" in Path.cwd().parts or "windsurf" in str(Path(__file__)):
|
||||
return IDEType.WINDSURF
|
||||
|
||||
return IDEType.UNKNOWN
|
||||
|
||||
|
||||
def setup_ide(project_root: Path, config: Dict[str, Any]) -> bool:
|
||||
"""为检测到的 IDE 设置项目"""
|
||||
ide = detect_ide()
|
||||
|
||||
if ide == IDEType.CURSOR:
|
||||
cursor_generate(project_root, config)
|
||||
return True
|
||||
elif ide == IDEType.WINDSURF:
|
||||
setup_windsurf(project_root, config)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def generate_ide_rules(ide: IDEType, project_config: Dict[str, Any]) -> str:
|
||||
"""为指定 IDE 生成规则"""
|
||||
if ide == IDEType.CURSOR:
|
||||
from .cursor_adapter import generate_cursorrules_content
|
||||
return generate_cursorrules_content(project_config)
|
||||
elif ide == IDEType.WINDSURF:
|
||||
from .windsurf_adapter import generate_windsurfrules
|
||||
return generate_windsurfrules(project_config)
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def get_supported_ides() -> List[str]:
|
||||
"""获取支持的 IDE 列表"""
|
||||
return [e.value for e in IDEType if e != IDEType.UNKNOWN]
|
||||
|
||||
|
||||
def auto_setup(project_root: Path, config: Dict[str, Any]) -> Dict[str, bool]:
|
||||
"""自动为所有支持的 IDE 生成配置"""
|
||||
results = {}
|
||||
|
||||
results["cursor"] = _setup_cursor(project_root, config)
|
||||
results["windsurf"] = _setup_windsurf(project_root, config)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def _setup_cursor(project_root: Path, config: Dict[str, Any]) -> bool:
|
||||
try:
|
||||
cursor_generate(project_root, config)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def _setup_windsurf(project_root: Path, config: Dict[str, Any]) -> bool:
|
||||
try:
|
||||
setup_windsurf(project_root, config)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
Windsurf IDE Adapter
|
||||
NovelMaster Core Engine - Configurators
|
||||
|
||||
为 Windsurf IDE 生成配置和 Cascade 上下文
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any
|
||||
import json
|
||||
|
||||
|
||||
def generate_windsurfrules(project_config: Dict[str, Any]) -> str:
|
||||
"""生成 .windsurfrules 文件内容"""
|
||||
|
||||
genesis = project_config.get("genesis_contract", {})
|
||||
|
||||
rules = f"""# NovelMaster Windsurf Rules
|
||||
|
||||
## 项目配置
|
||||
- 名称: {project_config.get("project_name", "未命名")}
|
||||
- 题材: {project_config.get("genre", "网文")}
|
||||
|
||||
## Genesis Contract
|
||||
{genesis.get("description", "")}
|
||||
|
||||
## Cascade 上下文
|
||||
使用以下上下文进行创作:
|
||||
1. 核心欲望: {genesis.get("core_desire", {}).get("primary", "未设置")}
|
||||
2. 伦理沙盒: {genesis.get("ethical_inversion", {}).get("inverted_norms", [])}
|
||||
3. 奇观设定: {genesis.get("core_spectacle", {}).get("ordinary_state", "未设置")}
|
||||
|
||||
## 写作工作流
|
||||
1. Planner Agent 调度 catharsis_model
|
||||
2. Writer Agent 生成章节
|
||||
3. Handoff 帧交接
|
||||
4. Dashboard 监控
|
||||
|
||||
## 状态文件
|
||||
- 状态文件: .noma/state.json
|
||||
- 账本: .noma/ledger.json
|
||||
- Hook池: .noma/hooks_pool.json
|
||||
"""
|
||||
|
||||
return rules
|
||||
|
||||
|
||||
def generate_cascade_context(project_root: Path) -> Dict[str, Any]:
|
||||
"""生成 Cascade 上下文"""
|
||||
state_file = project_root / ".noma" / "state.json"
|
||||
|
||||
context = {
|
||||
"project_root": str(project_root),
|
||||
"noma_dir": str(project_root / ".noma"),
|
||||
"genesis_contract": {},
|
||||
"current_chapter": 1,
|
||||
"hooks": [],
|
||||
"ledger": {}
|
||||
}
|
||||
|
||||
if state_file.exists():
|
||||
try:
|
||||
with open(state_file, "r", encoding="utf-8") as f:
|
||||
state = json.load(f)
|
||||
context.update(state)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return context
|
||||
|
||||
|
||||
def setup_windsurf(project_root: Path, config: Dict[str, Any]) -> None:
|
||||
"""设置 Windsurf 项目"""
|
||||
rules_file = project_root / ".windsurfrules"
|
||||
rules_content = generate_windsurfrules(config)
|
||||
with open(rules_file, "w", encoding="utf-8") as f:
|
||||
f.write(rules_content)
|
||||
Reference in New Issue
Block a user