Compare commits
4 Commits
6284124546
...
84ed61ac97
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84ed61ac97 | ||
|
|
38d5cec53e | ||
|
|
892e5977ed | ||
|
|
cf86ab688a |
@ -479,6 +479,16 @@ rule_effectiveness: R10=未验证(任务开始前未触发,事后归因)
|
|||||||
- **固化**:哪些跨项目重复出现的阻塞模式、哪些有效实践,值得写进 CONVENTIONS
|
- **固化**:哪些跨项目重复出现的阻塞模式、哪些有效实践,值得写进 CONVENTIONS
|
||||||
- **遗忘**:哪些休眠项目(90天无快照)的 AI 文档可以归档,哪些 CONVENTIONS 规则已过时
|
- **遗忘**:哪些休眠项目(90天无快照)的 AI 文档可以归档,哪些 CONVENTIONS 规则已过时
|
||||||
|
|
||||||
|
### 梦核写入纪律(蒸馏,不是追加)
|
||||||
|
|
||||||
|
梦核的产出是**替换操作,不是追加**。每次梦核后遵守:
|
||||||
|
|
||||||
|
1. **项目专属规则不进全局** → 写到该项目的 `.blueprint/rules.md`,不写入 CONVENTIONS
|
||||||
|
2. **全局规则上限 ≤ 25 条** → 超出则先合并/删除再新增;规则总量是飞轮健康度的信号
|
||||||
|
3. **改原条目,不加新条目** → R10 置信度需降,直接修改 R10 的 confidence 字段,不在旁边另起一条注释
|
||||||
|
4. **置信度元数据就地维护** → confidence / evidence_count / failure_cases 内嵌在各规则条目中,不另建文件
|
||||||
|
5. **一次性洞察不固化** → 梦核分析在对话中消费完毕,不另存 .md 文件;原料(复盘笔记)已在飞轮中,随时可重新生成
|
||||||
|
|
||||||
### 闭环路径
|
### 闭环路径
|
||||||
|
|
||||||
两条并行的反馈路径,速度不同:
|
两条并行的反馈路径,速度不同:
|
||||||
@ -882,9 +892,9 @@ scope 描述规则的正向适用范围,**boundaries 描述已知的反向边
|
|||||||
- **scope**: `tauri`
|
- **scope**: `tauri`
|
||||||
- **触发条件**:在 `src-tauri/src/commands/` 下新增 `#[tauri::command]` 函数
|
- **触发条件**:在 `src-tauri/src/commands/` 下新增 `#[tauri::command]` 函数
|
||||||
- **自动动作**:读取 `src/lib/commands.ts`,确认是否有对应封装;缺失则提示补写,不阻止执行
|
- **自动动作**:读取 `src/lib/commands.ts`,确认是否有对应封装;缺失则提示补写,不阻止执行
|
||||||
- **confidence**: 0.90
|
- **confidence**: 0.95
|
||||||
- **evidence_count**: 8
|
- **evidence_count**: 12
|
||||||
- **derived_from**: 多次发生前后端接口断层(命令已实现但 commands.ts 未同步,前端调用报错)
|
- **derived_from**: 多次发生前后端接口断层(命令已实现但 commands.ts 未同步,前端调用报错);梦核 2026-07-04:12 次命中,0 次返工,最稳信号
|
||||||
|
|
||||||
#### R02 — 任务卡无 acceptance 时先补写再动代码
|
#### R02 — 任务卡无 acceptance 时先补写再动代码
|
||||||
- **scope**: `universal`
|
- **scope**: `universal`
|
||||||
@ -938,9 +948,12 @@ scope 描述规则的正向适用范围,**boundaries 描述已知的反向边
|
|||||||
- **scope**: `universal`
|
- **scope**: `universal`
|
||||||
- **触发条件**:前端组件显示运行状态、健康状态、操作结果等实时信息
|
- **触发条件**:前端组件显示运行状态、健康状态、操作结果等实时信息
|
||||||
- **自动动作**:检查对应后端是否做了真实检测而非硬编码;发现硬编码状态时标记为需修复
|
- **自动动作**:检查对应后端是否做了真实检测而非硬编码;发现硬编码状态时标记为需修复
|
||||||
- **confidence**: 0.87
|
- **confidence**: 0.72
|
||||||
- **evidence_count**: 5
|
- **evidence_count**: 3
|
||||||
- **derived_from**: 设置页 MCP 状态硬编码为"运行中",注入失败时 toast 始终显示成功——UI 掩盖真实问题
|
- **derived_from**: 设置页 MCP 状态硬编码为"运行中",注入失败时 toast 始终显示成功——UI 掩盖真实问题
|
||||||
|
- **boundaries**: 展示类状态(loading spinner、空状态提示)属 UI 职责,不适用本规则;本规则仅限"系统真实运行状态"类展示
|
||||||
|
- **failure_cases**:
|
||||||
|
- 2026-07-04(梦核归因):3 次命中全部伴随返工(100%),规则触发但未阻止问题——根因是"状态硬编码"发生在编写时,规则检查发生在展示层,时序错位;建议在写 Tauri command 时即检查返回值是否真实(与 R01 联动)
|
||||||
|
|
||||||
#### R09 — 自动化边界:事件触发只标 🔵,不标 ✅
|
#### R09 — 自动化边界:事件触发只标 🔵,不标 ✅
|
||||||
- **scope**: `universal`
|
- **scope**: `universal`
|
||||||
@ -954,9 +967,12 @@ scope 描述规则的正向适用范围,**boundaries 描述已知的反向边
|
|||||||
- **scope**: `universal`
|
- **scope**: `universal`
|
||||||
- **触发条件**:实现与外部客户端的协议对接(MCP、LSP、WebSocket、SSE、OAuth 等)
|
- **触发条件**:实现与外部客户端的协议对接(MCP、LSP、WebSocket、SSE、OAuth 等)
|
||||||
- **自动动作**:在开始实现前,先通过文档或工具(curl、抓包)确认客户端实际发出的请求格式;不基于"通用规范"假设行为
|
- **自动动作**:在开始实现前,先通过文档或工具(curl、抓包)确认客户端实际发出的请求格式;不基于"通用规范"假设行为
|
||||||
- **confidence**: 0.85
|
- **confidence**: 0.60
|
||||||
- **evidence_count**: 3
|
- **evidence_count**: 6
|
||||||
- **derived_from**: Claude Code MCP 客户端用 GET 发起 SSE 握手,炼境只接受 POST 导致 405,MCP 整体失效
|
- **derived_from**: Claude Code MCP 客户端用 GET 发起 SSE 握手,炼境只接受 POST 导致 405,MCP 整体失效
|
||||||
|
- **boundaries**: 实时协议(WebSocket、SSE)的完整握手序列难以通过 curl 完全预验证,需配合协议库调试工具(MCP Inspector 等);本规则防的是"基于规范假设而不看实际请求",不能防"验证了但实现仍有差"
|
||||||
|
- **failure_cases**:
|
||||||
|
- 2026-07-04(梦核归因):6 次命中中 5 次伴随返工(83%),显示规则触发后问题仍发生——根因是协议对接本身复杂度高,"验证客户端行为"这一步经常被跳过或验证不够深入;建议将规则收窄为强制前置步骤:实现前必须有一条 curl/工具调用记录证明验证已执行
|
||||||
|
|
||||||
#### R11 — 自动执行规则失效时必须记录失败案例
|
#### R11 — 自动执行规则失效时必须记录失败案例
|
||||||
- **scope**: `universal`
|
- **scope**: `universal`
|
||||||
@ -979,9 +995,9 @@ scope 描述规则的正向适用范围,**boundaries 描述已知的反向边
|
|||||||
- **scope**: `universal`
|
- **scope**: `universal`
|
||||||
- **触发条件**:M 或 L 复杂度任务卡准备标记 ✅ done
|
- **触发条件**:M 或 L 复杂度任务卡准备标记 ✅ done
|
||||||
- **自动动作**:acceptance 所述验证路径须由人或 agent **通过功能自身入口**真实走通一次(agent 按钮载体就近选择:Web 服务=HTTP API、CLI=命令、桌面应用=测试调用同一函数、UI 呈现层=Playwright 兜底)。禁止绕过功能手改产物冒充验证;agent 走通的关键路径顺手固化为一条测试(侦察→驻军),一次性验收不固化
|
- **自动动作**:acceptance 所述验证路径须由人或 agent **通过功能自身入口**真实走通一次(agent 按钮载体就近选择:Web 服务=HTTP API、CLI=命令、桌面应用=测试调用同一函数、UI 呈现层=Playwright 兜底)。禁止绕过功能手改产物冒充验证;agent 走通的关键路径顺手固化为一条测试(侦察→驻军),一次性验收不固化
|
||||||
- **confidence**: 0.80
|
- **confidence**: 0.88
|
||||||
- **evidence_count**: 2
|
- **evidence_count**: 11
|
||||||
- **derived_from**: noteapp manifest 被手改导致 schema 约束修复未获真实验证、autoforphone 接线被命令行代办导致 G7 按钮未走通——手动替代掩盖功能真实状态(2026-07-03 用户裁决 + MCP 治理三件套 agent 实测首证)
|
- **derived_from**: noteapp manifest 被手改导致 schema 约束修复未获真实验证、autoforphone 接线被命令行代办导致 G7 按钮未走通——手动替代掩盖功能真实状态(2026-07-03 用户裁决 + MCP 治理三件套 agent 实测首证);梦核 2026-07-04:11 次命中,9% 返工率,高频高效
|
||||||
|
|
||||||
### 规则演进路径
|
### 规则演进路径
|
||||||
|
|
||||||
|
|||||||
@ -3,19 +3,22 @@
|
|||||||
> 把此文件粘贴给任何 AI Agent,让它了解本项目的 git 工作方式。由炼境接入包分发。
|
> 把此文件粘贴给任何 AI Agent,让它了解本项目的 git 工作方式。由炼境接入包分发。
|
||||||
> `ONBOARDING_MANAGED` 标记块由炼境版本化管理(重跑接入包可原位升级),块外可自由补充项目特有约定。
|
> `ONBOARDING_MANAGED` 标记块由炼境版本化管理(重跑接入包可原位升级),块外可自由补充项目特有约定。
|
||||||
|
|
||||||
<!-- ONBOARDING_MANAGED_START version="1.2.0" -->
|
<!-- ONBOARDING_MANAGED_START version="1.3.0" -->
|
||||||
|
|
||||||
## 分支策略
|
## 分支策略(复杂度感知)
|
||||||
|
|
||||||
```
|
```
|
||||||
dev ← 日常开发在这里 commit/push
|
main/master ← 主分支,保持稳定
|
||||||
↓
|
↑
|
||||||
main ← 稳定分支,通过 PR 合入(合入时触发 CI code review)
|
├── 简单改动 → 直接 push main/master
|
||||||
|
└── 功能性改动 → feat/<name> 分支 → PR → main/master
|
||||||
```
|
```
|
||||||
|
|
||||||
- 小改动可直接 push `dev`
|
**简单改动(直接推主分支)**:bug fix、chore、docs、style、单文件小改,行为对外无变化。
|
||||||
- 功能完整后开 PR(dev → main)
|
|
||||||
- 不要直接 push `main`,除非紧急热修复
|
**功能性改动(开 feat/* 分支 + PR)**:新功能、重构、涉及多模块的 refactor。由 agent 根据改动文件数和性质自判,无需蓝图标签。
|
||||||
|
|
||||||
|
分支命名:`feat/<功能简述>`,如 `feat/login-sms`、`feat/order-pagination`。
|
||||||
|
|
||||||
## Commit 规范(lefthook 强制)
|
## Commit 规范(lefthook 强制)
|
||||||
|
|
||||||
@ -81,7 +84,7 @@ PR 别攒太大(建议每 3~5 个 commit 或几百行内就开一次),否
|
|||||||
```
|
```
|
||||||
1. Read .claude/liangjing.json → 取出 project_id
|
1. Read .claude/liangjing.json → 取出 project_id
|
||||||
2. 调用 MCP 工具 create_pull_request:
|
2. 调用 MCP 工具 create_pull_request:
|
||||||
{ "project_id": "<id>", "head": "dev", "base": "main",
|
{ "project_id": "<id>", "head": "feat/<name>", "base": "main",
|
||||||
"title": "<Conventional Commits 格式>", "body": "<变更摘要>" }
|
"title": "<Conventional Commits 格式>", "body": "<变更摘要>" }
|
||||||
3. 炼境内部用存储的 Gitea 凭证调 API,返回 pr_url
|
3. 炼境内部用存储的 Gitea 凭证调 API,返回 pr_url
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "dev-manager-tauri"
|
name = "dev-manager-tauri"
|
||||||
version = "0.1.18"
|
version = "0.1.19"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@ -13,4 +13,4 @@ pre-commit:
|
|||||||
commit-msg:
|
commit-msg:
|
||||||
commands:
|
commands:
|
||||||
conventional:
|
conventional:
|
||||||
run: "head -1 \"{1}\" | grep -qE '^(feat|fix|docs|chore|refactor|ci|perf|style|test|build|revert)(\\(.+\\))?!?: .+' || exit 1"
|
run: "head -1 .git/COMMIT_EDITMSG | grep -qE '^(feat|fix|docs|chore|refactor|ci|perf|style|test|build|revert)(\\(.+\\))?!?: .+' || exit 1"
|
||||||
|
|||||||
@ -827,6 +827,133 @@ pub fn gitea_api_merge_pull_request(project_id: &str, pr_number: i64) -> Result<
|
|||||||
Ok(format!("PR #{pr_number} 已成功合并({owner}/{repo_name})"))
|
Ok(format!("PR #{pr_number} 已成功合并({owner}/{repo_name})"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── MCP 工具:一键建仓库 + 配置 remote ───────────────────────────────────────
|
||||||
|
|
||||||
|
/// 为项目在默认 Gitea 实例上创建远程仓库,并配置本地 git remote origin。
|
||||||
|
/// 幂等:仓库已存在(409)则直接绑定;remote 已配置则 set-url 更新。
|
||||||
|
pub fn gitea_api_setup_repo(
|
||||||
|
project_id: &str,
|
||||||
|
repo_name: Option<&str>,
|
||||||
|
private: bool,
|
||||||
|
) -> Result<String, String> {
|
||||||
|
let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
// 项目基本信息
|
||||||
|
let (project_name, win_path): (String, Option<String>) = conn
|
||||||
|
.query_row(
|
||||||
|
"SELECT pp.name, pw.win_path
|
||||||
|
FROM project_workspaces pw
|
||||||
|
JOIN project_profiles pp ON pp.id = pw.profile_id
|
||||||
|
WHERE pw.id = ?1",
|
||||||
|
params![project_id],
|
||||||
|
|r| Ok((r.get(0)?, r.get(1)?)),
|
||||||
|
)
|
||||||
|
.map_err(|_| format!("项目 {} 不存在", project_id))?;
|
||||||
|
|
||||||
|
// 默认 Gitea 实例
|
||||||
|
let (instance_id, base_url, token): (String, String, String) = conn
|
||||||
|
.query_row(
|
||||||
|
"SELECT id, url, access_token FROM gitea_instances WHERE is_default = 1 LIMIT 1",
|
||||||
|
[],
|
||||||
|
|r| Ok((r.get(0)?, r.get(1)?, r.get(2)?)),
|
||||||
|
)
|
||||||
|
.map_err(|_| "未配置默认 Gitea 实例,请先在炼境 UI 中添加并设为默认".to_string())?;
|
||||||
|
|
||||||
|
// 仓库名 slug 化(保留 ASCII 字母数字 + - _ .);空字符串等同未传
|
||||||
|
let final_repo_name = repo_name.filter(|s| !s.trim().is_empty()).map(|s| s.to_string()).unwrap_or_else(|| {
|
||||||
|
let slug: String = project_name
|
||||||
|
.to_ascii_lowercase()
|
||||||
|
.replace(' ', "-")
|
||||||
|
.chars()
|
||||||
|
.filter(|c| c.is_ascii_alphanumeric() || *c == '-' || *c == '_' || *c == '.')
|
||||||
|
.collect();
|
||||||
|
if slug.is_empty() {
|
||||||
|
format!("project-{}", &project_id[..8.min(project_id.len())])
|
||||||
|
} else {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 仓库拥有者(从 token 获取登录名)
|
||||||
|
let owner = gitea_api_get_user(&base_url, &token)?.login;
|
||||||
|
|
||||||
|
// 创建仓库,409=已存在时直接绑定
|
||||||
|
let (clone_url, already_existed) = match ureq::post(&format!("{base_url}/api/v1/user/repos"))
|
||||||
|
.set("Authorization", &format!("token {token}"))
|
||||||
|
.send_json(serde_json::json!({
|
||||||
|
"name": final_repo_name,
|
||||||
|
"description": format!("{} — 由炼境自动创建", project_name),
|
||||||
|
"private": private,
|
||||||
|
"auto_init": false,
|
||||||
|
})) {
|
||||||
|
Ok(resp) => {
|
||||||
|
let json: serde_json::Value =
|
||||||
|
resp.into_json().map_err(|e| format!("解析响应失败: {e}"))?;
|
||||||
|
let url = json["clone_url"].as_str().ok_or("响应缺少 clone_url")?.to_string();
|
||||||
|
(url, false)
|
||||||
|
}
|
||||||
|
Err(ureq::Error::Status(409, _)) => {
|
||||||
|
let json = gitea_api_get_repo(&base_url, &token, &owner, &final_repo_name)?;
|
||||||
|
let url = json["clone_url"].as_str().ok_or("响应缺少 clone_url")?.to_string();
|
||||||
|
(url, true)
|
||||||
|
}
|
||||||
|
Err(e) => return Err(api_err("创建仓库失败", e)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// 写入炼境 DB 绑定关系
|
||||||
|
upsert_repo_link(&conn, &instance_id, project_id, &owner, &final_repo_name, Some(&clone_url))?;
|
||||||
|
|
||||||
|
// 配置本地 git remote origin
|
||||||
|
let remote_status = configure_git_remote(win_path.as_deref(), &clone_url);
|
||||||
|
|
||||||
|
let existed_tag = if already_existed { "已存在,直接绑定" } else { "新建" };
|
||||||
|
let remote_tag = match &remote_status {
|
||||||
|
Ok(action) => format!("✅ {action}"),
|
||||||
|
Err(e) => format!("⚠️ {e}"),
|
||||||
|
};
|
||||||
|
let mut out = format!(
|
||||||
|
"Gitea 仓库已就绪:{base_url}/{owner}/{final_repo_name}\n\n\
|
||||||
|
- 仓库:{owner}/{final_repo_name}({existed_tag})\n\
|
||||||
|
- 炼境绑定:✅ project_id 已关联\n\
|
||||||
|
- git remote origin:{remote_tag}\n"
|
||||||
|
);
|
||||||
|
if remote_status.is_ok() {
|
||||||
|
out.push_str("\n建议下一步:git push -u origin main,然后调用 setup_webhook 注册 webhook。");
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 配置本地仓库的 git remote origin(add 或 set-url,幂等)
|
||||||
|
fn configure_git_remote(win_path: Option<&str>, clone_url: &str) -> Result<String, String> {
|
||||||
|
let path = win_path.ok_or_else(|| "项目无本地路径".to_string())?;
|
||||||
|
if !std::path::Path::new(path).join(".git").exists() {
|
||||||
|
return Err("本地目录无 .git,跳过 remote 配置".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let has_origin = std::process::Command::new("git")
|
||||||
|
.args(["-C", path, "remote", "get-url", "origin"])
|
||||||
|
.output()
|
||||||
|
.map(|o| o.status.success())
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
let out = if has_origin {
|
||||||
|
std::process::Command::new("git")
|
||||||
|
.args(["-C", path, "remote", "set-url", "origin", clone_url])
|
||||||
|
.output()
|
||||||
|
} else {
|
||||||
|
std::process::Command::new("git")
|
||||||
|
.args(["-C", path, "remote", "add", "origin", clone_url])
|
||||||
|
.output()
|
||||||
|
}
|
||||||
|
.map_err(|e| format!("执行 git remote 失败: {e}"))?;
|
||||||
|
|
||||||
|
if out.status.success() {
|
||||||
|
Ok(if has_origin { "origin set-url 更新成功".to_string() } else { "origin 已添加".to_string() })
|
||||||
|
} else {
|
||||||
|
Err(String::from_utf8_lossy(&out.stderr).trim().to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@ -280,6 +280,19 @@ pub fn tools_list_result() -> Value {
|
|||||||
},
|
},
|
||||||
"required": ["project_id"]
|
"required": ["project_id"]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "setup_gitea_repo",
|
||||||
|
"description": "为项目在默认 Gitea 实例上创建远程仓库,并将本地 git remote origin 指向新仓库(幂等:仓库已存在则直接绑定,remote 已有则 set-url 更新)。创建后炼境自动记录绑定关系,后续可调用 setup_webhook 注册 webhook。需先在炼境 UI 配置一个默认 Gitea 实例。",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"project_id": { "type": "string", "description": "项目 workspace ID(来自 list_group_projects 的返回结果)" },
|
||||||
|
"repo_name": { "type": "string", "description": "Gitea 仓库名;省略则用项目名自动 slug 化(非 ASCII 字符过滤掉)" },
|
||||||
|
"private": { "type": "boolean", "description": "是否创建私有仓库,默认 false(公开)" }
|
||||||
|
},
|
||||||
|
"required": ["project_id"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -569,6 +582,12 @@ pub async fn tools_call(group_id: &str, params: Option<&Value>) -> Value {
|
|||||||
crate::commands::risk::predict_task_risk(&conn, pid, scope, &files)
|
crate::commands::risk::predict_task_risk(&conn, pid, scope, &files)
|
||||||
.and_then(|r| serde_json::to_string_pretty(&r).map_err(|e| e.to_string()))
|
.and_then(|r| serde_json::to_string_pretty(&r).map_err(|e| e.to_string()))
|
||||||
}
|
}
|
||||||
|
"setup_gitea_repo" => {
|
||||||
|
let pid = args.get("project_id").and_then(|v| v.as_str()).unwrap_or("");
|
||||||
|
let repo_name = args.get("repo_name").and_then(|v| v.as_str());
|
||||||
|
let private = args.get("private").and_then(|v| v.as_bool()).unwrap_or(false);
|
||||||
|
crate::commands::gitea::gitea_api_setup_repo(pid, repo_name, private)
|
||||||
|
}
|
||||||
"apply_onboarding_pack" => {
|
"apply_onboarding_pack" => {
|
||||||
let pid = args.get("project_id").and_then(|v| v.as_str()).unwrap_or("");
|
let pid = args.get("project_id").and_then(|v| v.as_str()).unwrap_or("");
|
||||||
resolve_project_root(&gid, pid).and_then(|root| {
|
resolve_project_root(&gid, pid).and_then(|root| {
|
||||||
@ -1149,6 +1168,7 @@ mod tests {
|
|||||||
assert!(names.contains(&"predict_task_risk"), "缺少 predict_task_risk");
|
assert!(names.contains(&"predict_task_risk"), "缺少 predict_task_risk");
|
||||||
assert!(names.contains(&"ingest_git_history"), "缺少 ingest_git_history");
|
assert!(names.contains(&"ingest_git_history"), "缺少 ingest_git_history");
|
||||||
assert!(names.contains(&"unregister_project"), "缺少 unregister_project");
|
assert!(names.contains(&"unregister_project"), "缺少 unregister_project");
|
||||||
|
assert!(names.contains(&"setup_gitea_repo"), "缺少 setup_gitea_repo");
|
||||||
// 每个工具都有 description 和 inputSchema
|
// 每个工具都有 description 和 inputSchema
|
||||||
for tool in tools {
|
for tool in tools {
|
||||||
let name = tool["name"].as_str().unwrap_or("?");
|
let name = tool["name"].as_str().unwrap_or("?");
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "dev-manager-tauri",
|
"productName": "dev-manager-tauri",
|
||||||
"version": "0.1.18",
|
"version": "0.1.19",
|
||||||
"identifier": "com.yangzhixiang.dev-manager-tauri",
|
"identifier": "com.yangzhixiang.dev-manager-tauri",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "pnpm dev",
|
"beforeDevCommand": "pnpm dev",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user