jvibe 1.0.9 → 1.1.0
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.
- package/README.md +3 -1
- package/bin/jvibe.js +15 -1
- package/lib/migrate.js +1 -2
- package/lib/migrations/index.js +7 -1
- package/package.json +1 -1
- package/scripts/uninstall.js +83 -0
- package/scripts/upgrade.js +36 -82
- package/template/.claude/commands/JVibe:init.md +11 -4
- package/template/.claude/commands/JVibe:migrate.md +4 -1
- package/template/docs/core/Project.md +9 -0
- package/template/docs/core/Standards.md +40 -0
package/README.md
CHANGED
|
@@ -158,8 +158,10 @@ TODO 完成情况 → 功能状态
|
|
|
158
158
|
| `jvibe init` | 初始化 JVibe 项目 |
|
|
159
159
|
| `jvibe init --mode=minimal` | 最小化初始化(仅 Core 文档) |
|
|
160
160
|
| `jvibe init --force` | 强制覆盖已存在的配置 |
|
|
161
|
-
| `jvibe upgrade` |
|
|
161
|
+
| `jvibe upgrade` | 升级到最新版本(默认卸载重装) |
|
|
162
162
|
| `jvibe upgrade --check` | 仅检查更新 |
|
|
163
|
+
| `jvibe upgrade --migrate` | 仅执行旧版迁移 |
|
|
164
|
+
| `jvibe uninstall` | 卸载项目内 JVibe 配置 |
|
|
163
165
|
| `jvibe status` | 查看项目配置状态 |
|
|
164
166
|
| `jvibe validate` | 验证项目配置 |
|
|
165
167
|
|
package/bin/jvibe.js
CHANGED
|
@@ -34,7 +34,7 @@ program
|
|
|
34
34
|
// upgrade 命令
|
|
35
35
|
program
|
|
36
36
|
.command('upgrade')
|
|
37
|
-
.description('
|
|
37
|
+
.description('升级到最新版本(默认卸载重装)')
|
|
38
38
|
.option('--check', '仅检查更新,不执行升级', false)
|
|
39
39
|
.option('--force', '强制升级,跳过确认', false)
|
|
40
40
|
.option('--migrate', '仅执行迁移,不更新到最新版本', false)
|
|
@@ -53,6 +53,20 @@ program
|
|
|
53
53
|
await upgrade({ ...options, migrate: true });
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
+
// uninstall 命令
|
|
57
|
+
program
|
|
58
|
+
.command('uninstall')
|
|
59
|
+
.description('卸载项目内的 JVibe 配置与核心文档')
|
|
60
|
+
.option('--purge-project-docs', '同时移除 docs/project', false)
|
|
61
|
+
.option('--no-backup', '不创建备份', false)
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
const uninstall = require('../scripts/uninstall');
|
|
64
|
+
await uninstall({
|
|
65
|
+
purgeProjectDocs: options.purgeProjectDocs,
|
|
66
|
+
backup: options.backup
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
56
70
|
// status 命令
|
|
57
71
|
program
|
|
58
72
|
.command('status')
|
package/lib/migrate.js
CHANGED
|
@@ -494,10 +494,9 @@ async function checkContentMigration(projectDir, currentVersion) {
|
|
|
494
494
|
description: '核心文档需要强制重构(以 template/docs/core 为准)'
|
|
495
495
|
});
|
|
496
496
|
}
|
|
497
|
-
return result;
|
|
498
497
|
}
|
|
499
498
|
|
|
500
|
-
//
|
|
499
|
+
// 模板检测后继续合并版本迁移配置
|
|
501
500
|
if (migrationsConfig && currentVersion) {
|
|
502
501
|
const configResult = migrationsConfig.checkAIMigrationRequired(currentVersion);
|
|
503
502
|
if (configResult.required) {
|
package/lib/migrations/index.js
CHANGED
|
@@ -226,7 +226,13 @@ function generateMigrationPrompt(fromVersion) {
|
|
|
226
226
|
if (result.changes.renamed.length > 0) {
|
|
227
227
|
prompt += `## 重命名的字段\n\n`;
|
|
228
228
|
for (const change of result.changes.renamed) {
|
|
229
|
-
|
|
229
|
+
const renameLabel = change.oldName && change.newName
|
|
230
|
+
? `${change.oldName} → ${change.newName}`
|
|
231
|
+
: (change.field || change.description || '重命名');
|
|
232
|
+
prompt += `- ${change.file}: ${renameLabel}\n`;
|
|
233
|
+
if (change.description && renameLabel !== change.description) {
|
|
234
|
+
prompt += ` - ${change.description}\n`;
|
|
235
|
+
}
|
|
230
236
|
}
|
|
231
237
|
prompt += `\n`;
|
|
232
238
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JVibe Uninstall Script
|
|
3
|
+
* 卸载项目内的 JVibe 配置与核心文档
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 卸载 JVibe 配置
|
|
12
|
+
* @param {Object} options - 卸载选项
|
|
13
|
+
* @param {boolean} options.purgeProjectDocs - 是否移除 docs/project
|
|
14
|
+
* @param {boolean} options.backup - 是否创建备份
|
|
15
|
+
* @param {boolean} options.showNextSteps - 是否输出下一步提示
|
|
16
|
+
*/
|
|
17
|
+
async function uninstall(options = {}) {
|
|
18
|
+
const purgeProjectDocs = options.purgeProjectDocs || false;
|
|
19
|
+
const backupEnabled = options.backup !== false;
|
|
20
|
+
const showNextSteps = options.showNextSteps !== false;
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
|
|
23
|
+
console.log(chalk.blue('\n🧹 正在卸载 JVibe...\n'));
|
|
24
|
+
|
|
25
|
+
const targets = [
|
|
26
|
+
{ relPath: '.claude', label: '.claude/' },
|
|
27
|
+
{ relPath: 'docs/core', label: 'docs/core/' },
|
|
28
|
+
{ relPath: 'docs/.jvibe', label: 'docs/.jvibe/' },
|
|
29
|
+
{ relPath: '.jvibe-state.json', label: '.jvibe-state.json' },
|
|
30
|
+
{ relPath: 'docs/.jvibe-state.json', label: 'docs/.jvibe-state.json' },
|
|
31
|
+
{ relPath: 'docs/project', label: 'docs/project/', optional: true }
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const existingTargets = [];
|
|
35
|
+
for (const target of targets) {
|
|
36
|
+
if (target.optional && !purgeProjectDocs) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const fullPath = path.join(cwd, target.relPath);
|
|
40
|
+
if (await fs.pathExists(fullPath)) {
|
|
41
|
+
existingTargets.push({ ...target, fullPath });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (existingTargets.length === 0) {
|
|
46
|
+
console.log(chalk.yellow('⚠️ 未发现可卸载的 JVibe 配置'));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let backupDir = null;
|
|
51
|
+
if (backupEnabled) {
|
|
52
|
+
backupDir = path.join(cwd, `.jvibe-uninstall-backup-${Date.now()}`);
|
|
53
|
+
await fs.ensureDir(backupDir);
|
|
54
|
+
|
|
55
|
+
for (const target of existingTargets) {
|
|
56
|
+
const destPath = path.join(backupDir, target.relPath);
|
|
57
|
+
await fs.ensureDir(path.dirname(destPath));
|
|
58
|
+
await fs.copy(target.fullPath, destPath);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const target of existingTargets) {
|
|
63
|
+
await fs.remove(target.fullPath);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.log(chalk.green('\n✅ JVibe 卸载完成!'));
|
|
67
|
+
console.log(chalk.white('\n已移除:'));
|
|
68
|
+
for (const target of existingTargets) {
|
|
69
|
+
console.log(chalk.gray(` - ${target.label}`));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (backupDir) {
|
|
73
|
+
console.log(chalk.gray(`\n备份位置:${path.basename(backupDir)}/`));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (showNextSteps) {
|
|
77
|
+
console.log(chalk.yellow('\n📝 下一步:'));
|
|
78
|
+
console.log(chalk.white(' 1. 重新运行 jvibe init 或 /JVibe:init 初始化'));
|
|
79
|
+
console.log(chalk.white(' 2. 如需恢复,可从备份目录手动还原\n'));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = uninstall;
|
package/scripts/upgrade.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JVibe Upgrade Script
|
|
3
3
|
* 升级项目的 JVibe 配置到最新版本
|
|
4
|
-
*
|
|
4
|
+
* 默认执行卸载重装,可选保留旧迁移策略
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const fs = require('fs-extra');
|
|
@@ -13,6 +13,8 @@ const {
|
|
|
13
13
|
executeMigration,
|
|
14
14
|
printMigrationSummary
|
|
15
15
|
} = require('../lib/migrate');
|
|
16
|
+
const init = require('./init');
|
|
17
|
+
const uninstall = require('./uninstall');
|
|
16
18
|
|
|
17
19
|
const TEMPLATE_DIR = path.join(__dirname, '../template');
|
|
18
20
|
|
|
@@ -63,23 +65,47 @@ async function upgrade(options = {}) {
|
|
|
63
65
|
if (checkOnly) {
|
|
64
66
|
if (migrationPlan.needsMigration) {
|
|
65
67
|
console.log(chalk.yellow('\n📦 检测到旧版本,需要迁移'));
|
|
66
|
-
console.log(chalk.white(' 运行 jvibe upgrade
|
|
68
|
+
console.log(chalk.white(' 运行 jvibe upgrade 执行卸载重装\n'));
|
|
67
69
|
} else if (currentVersion === latestVersion) {
|
|
68
70
|
console.log(chalk.green('\n✅ 已是最新版本!\n'));
|
|
69
71
|
} else {
|
|
70
72
|
console.log(chalk.yellow(`\n📦 有新版本可用: ${latestVersion}`));
|
|
71
|
-
console.log(chalk.white(' 运行 jvibe upgrade
|
|
73
|
+
console.log(chalk.white(' 运行 jvibe upgrade 执行卸载重装\n'));
|
|
72
74
|
}
|
|
73
75
|
return;
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
if (!migrateOnly) {
|
|
79
|
+
if (!force) {
|
|
80
|
+
console.log(chalk.yellow('\n⚠️ 将执行卸载重装(重置 .claude/ 与 docs/core/)'));
|
|
81
|
+
console.log(chalk.white(' 使用 --force 选项跳过此确认'));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let mode = 'full';
|
|
85
|
+
if (await fs.pathExists(settingsPath)) {
|
|
86
|
+
try {
|
|
87
|
+
const settings = await fs.readJson(settingsPath);
|
|
88
|
+
mode = settings.jvibe?.mode || mode;
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// 读取失败则使用默认模式
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
await uninstall({ purgeProjectDocs: false, backup: true, showNextSteps: false });
|
|
95
|
+
await init({ mode, force: false });
|
|
96
|
+
|
|
97
|
+
console.log(chalk.green(`\n✅ 升级完成!`));
|
|
98
|
+
console.log(chalk.green(` 版本: ${currentVersion} → ${latestVersion}`));
|
|
99
|
+
console.log(chalk.gray('\n 已执行卸载重装(保留 docs/project/)\n'));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// migrate-only 模式保留旧迁移逻辑
|
|
77
104
|
if (!migrationPlan.needsMigration && currentVersion === latestVersion) {
|
|
78
|
-
console.log(chalk.green('\n✅
|
|
105
|
+
console.log(chalk.green('\n✅ 已是最新版本,无需迁移!\n'));
|
|
79
106
|
return;
|
|
80
107
|
}
|
|
81
108
|
|
|
82
|
-
// 5. 确认升级(如果没有 --force)
|
|
83
109
|
if (!force && (migrationPlan.needsMigration || currentVersion !== latestVersion)) {
|
|
84
110
|
console.log(chalk.yellow('\n⚠️ 即将执行以下操作:'));
|
|
85
111
|
|
|
@@ -92,12 +118,8 @@ async function upgrade(options = {}) {
|
|
|
92
118
|
|
|
93
119
|
console.log(chalk.white('\n 使用 --force 选项跳过此确认'));
|
|
94
120
|
console.log(chalk.white(' 或重新运行命令继续...\n'));
|
|
95
|
-
|
|
96
|
-
// 在非交互模式下直接继续
|
|
97
|
-
// 实际项目中可能需要 readline 来获取用户确认
|
|
98
121
|
}
|
|
99
122
|
|
|
100
|
-
// 6. 创建备份
|
|
101
123
|
console.log(chalk.gray('\n 创建备份...'));
|
|
102
124
|
const backupDir = path.join(cwd, '.jvibe-backup-' + Date.now());
|
|
103
125
|
if (hasClaudeDir) {
|
|
@@ -108,78 +130,11 @@ async function upgrade(options = {}) {
|
|
|
108
130
|
}
|
|
109
131
|
console.log(chalk.gray(` 备份已保存到: ${path.basename(backupDir)}/`));
|
|
110
132
|
|
|
111
|
-
// 7. 执行迁移(如果需要)
|
|
112
133
|
if (migrationPlan.needsMigration) {
|
|
113
134
|
await executeMigration(cwd, TEMPLATE_DIR, migrationPlan, latestVersion);
|
|
114
135
|
}
|
|
115
136
|
|
|
116
|
-
|
|
117
|
-
if (!migrateOnly && currentVersion !== latestVersion) {
|
|
118
|
-
console.log(chalk.yellow(`\n📦 正在升级到 ${latestVersion}...\n`));
|
|
119
|
-
|
|
120
|
-
// 更新 agents(如果迁移时没有更新)
|
|
121
|
-
if (migrationPlan.details.agentsToUpdate.length === 0) {
|
|
122
|
-
console.log(chalk.gray(' 更新 agents...'));
|
|
123
|
-
await fs.copy(
|
|
124
|
-
path.join(TEMPLATE_DIR, '.claude/agents'),
|
|
125
|
-
path.join(cwd, '.claude/agents'),
|
|
126
|
-
{ overwrite: true }
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// 更新 commands(如果迁移时没有更新)
|
|
131
|
-
if (migrationPlan.details.commandsToRename.length === 0) {
|
|
132
|
-
console.log(chalk.gray(' 更新 commands...'));
|
|
133
|
-
await fs.copy(
|
|
134
|
-
path.join(TEMPLATE_DIR, '.claude/commands'),
|
|
135
|
-
path.join(cwd, '.claude/commands'),
|
|
136
|
-
{ overwrite: true }
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// 更新 hooks(如果迁移时没有更新)
|
|
141
|
-
if (migrationPlan.details.hooksToUpdate.length === 0) {
|
|
142
|
-
console.log(chalk.gray(' 更新 hooks...'));
|
|
143
|
-
await fs.copy(
|
|
144
|
-
path.join(TEMPLATE_DIR, '.claude/hooks'),
|
|
145
|
-
path.join(cwd, '.claude/hooks'),
|
|
146
|
-
{ overwrite: true }
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// 补充任务交接文件(如不存在)
|
|
151
|
-
const handoffSrc = path.join(TEMPLATE_DIR, 'docs/.jvibe/tasks.yaml');
|
|
152
|
-
const handoffDir = path.join(cwd, 'docs/.jvibe');
|
|
153
|
-
const handoffDest = path.join(handoffDir, 'tasks.yaml');
|
|
154
|
-
if (await fs.pathExists(handoffSrc) && !await fs.pathExists(handoffDest)) {
|
|
155
|
-
await fs.ensureDir(handoffDir);
|
|
156
|
-
await fs.copy(handoffSrc, handoffDest, { overwrite: false });
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// 更新版本信息
|
|
160
|
-
let settings = {};
|
|
161
|
-
if (await fs.pathExists(settingsPath)) {
|
|
162
|
-
try {
|
|
163
|
-
settings = await fs.readJson(settingsPath);
|
|
164
|
-
} catch (e) {
|
|
165
|
-
// 读取失败则创建新配置
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
settings.jvibe = {
|
|
170
|
-
...settings.jvibe,
|
|
171
|
-
version: latestVersion,
|
|
172
|
-
upgradedAt: new Date().toISOString()
|
|
173
|
-
};
|
|
174
|
-
await fs.writeJson(settingsPath, settings, { spaces: 2 });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// 9. 清理旧备份(保留最新的)
|
|
178
|
-
// 可选:保留备份供用户手动清理
|
|
179
|
-
|
|
180
|
-
// 10. 输出成功信息
|
|
181
|
-
console.log(chalk.green(`\n✅ 升级完成!`));
|
|
182
|
-
|
|
137
|
+
console.log(chalk.green(`\n✅ 迁移完成!`));
|
|
183
138
|
if (migrationPlan.needsMigration) {
|
|
184
139
|
console.log(chalk.green(' 已完成旧版本迁移'));
|
|
185
140
|
}
|
|
@@ -190,7 +145,6 @@ async function upgrade(options = {}) {
|
|
|
190
145
|
console.log(chalk.gray(`\n 备份位置: ${path.basename(backupDir)}/`));
|
|
191
146
|
console.log(chalk.gray(' 如需回滚,请手动恢复备份文件'));
|
|
192
147
|
|
|
193
|
-
// 11. 检查是否需要 AI 内容迁移
|
|
194
148
|
if (migrationPlan.needsAIMigration) {
|
|
195
149
|
console.log(chalk.yellow('\n⚠️ 检测到文档内容需要智能迁移'));
|
|
196
150
|
console.log(chalk.yellow(' 以下内容需要 AI 介入处理:'));
|
|
@@ -207,7 +161,7 @@ async function upgrade(options = {}) {
|
|
|
207
161
|
console.error(chalk.red('\n❌ 升级失败:'), error.message);
|
|
208
162
|
|
|
209
163
|
// 提示备份位置
|
|
210
|
-
const backups = await findBackups(cwd);
|
|
164
|
+
const backups = await findBackups(cwd, ['.jvibe-backup-', '.jvibe-uninstall-backup-']);
|
|
211
165
|
if (backups.length > 0) {
|
|
212
166
|
console.log(chalk.yellow(` 最新备份: ${backups[0]}`));
|
|
213
167
|
}
|
|
@@ -221,11 +175,11 @@ async function upgrade(options = {}) {
|
|
|
221
175
|
* @param {string} dir - 项目目录
|
|
222
176
|
* @returns {Promise<string[]>}
|
|
223
177
|
*/
|
|
224
|
-
async function findBackups(dir) {
|
|
178
|
+
async function findBackups(dir, prefixes = ['.jvibe-backup-']) {
|
|
225
179
|
try {
|
|
226
180
|
const files = await fs.readdir(dir);
|
|
227
181
|
return files
|
|
228
|
-
.filter(f => f.startsWith(
|
|
182
|
+
.filter(f => prefixes.some(prefix => f.startsWith(prefix)))
|
|
229
183
|
.sort()
|
|
230
184
|
.reverse();
|
|
231
185
|
} catch (e) {
|
|
@@ -29,6 +29,7 @@ description: 初始化 JVibe 项目文档结构
|
|
|
29
29
|
- 模块清单(根据 AI 分析生成)
|
|
30
30
|
- 模块依赖关系
|
|
31
31
|
- 模块功能统计表(初始为空)
|
|
32
|
+
- 环境配置(项目根路径、代码根路径)
|
|
32
33
|
|
|
33
34
|
### Feature-List.md
|
|
34
35
|
|
|
@@ -207,13 +208,19 @@ questions:
|
|
|
207
208
|
3. **AI 分析规划**:生成模块架构、依赖关系、技术栈推荐
|
|
208
209
|
4. **用户确认/调整**:让用户确认或修改架构
|
|
209
210
|
5. 创建 `docs/` 目录
|
|
210
|
-
6.
|
|
211
|
-
|
|
211
|
+
6. 自动识别项目路径并写入 Project.md:
|
|
212
|
+
```yaml
|
|
213
|
+
detect_paths:
|
|
214
|
+
project_root: $PWD (包含 .git 或 .claude)
|
|
215
|
+
code_root: src/ | app/ | lib/ | .
|
|
216
|
+
```
|
|
217
|
+
7. 从模板复制并填充项目信息
|
|
218
|
+
8. 创建 4 个核心文档:
|
|
212
219
|
- **Project.md**:填充模块清单、架构图、技术栈
|
|
213
220
|
- **Feature-List.md**:空模板(后续逐个添加功能)
|
|
214
221
|
- **Standards.md**:基础模板
|
|
215
222
|
- **Appendix.md**:基础模板
|
|
216
|
-
|
|
223
|
+
9. **创建状态标记文件** `.jvibe-state.json`:
|
|
217
224
|
```json
|
|
218
225
|
{
|
|
219
226
|
"initialized": true,
|
|
@@ -222,7 +229,7 @@ questions:
|
|
|
222
229
|
"createdAt": "2026-01-11T10:00:00Z"
|
|
223
230
|
}
|
|
224
231
|
```
|
|
225
|
-
|
|
232
|
+
10. 输出确认信息
|
|
226
233
|
|
|
227
234
|
## 输出要求
|
|
228
235
|
|
|
@@ -79,6 +79,9 @@ project:
|
|
|
79
79
|
architecture: []
|
|
80
80
|
tech_stack: []
|
|
81
81
|
modules: []
|
|
82
|
+
paths:
|
|
83
|
+
project_root: $PWD (包含 .git 或 .claude)
|
|
84
|
+
code_root: src/ | app/ | lib/ | .
|
|
82
85
|
features: []
|
|
83
86
|
appendix:
|
|
84
87
|
entries: []
|
|
@@ -121,7 +124,7 @@ appendix:
|
|
|
121
124
|
#### 3.4 重构 Project
|
|
122
125
|
|
|
123
126
|
1. **按模板章节顺序重建**
|
|
124
|
-
2.
|
|
127
|
+
2. **填充项目事实**(架构、模块、接口、数据模型、代码落点、项目路径)
|
|
125
128
|
3. **更新模块功能统计**(从功能清单重新计算)
|
|
126
129
|
|
|
127
130
|
#### 3.5 重构 Standards / Appendix
|
|
@@ -228,3 +228,12 @@ src/modules/chat/
|
|
|
228
228
|
| chat_rooms | ChatModule | id, name, type, created_at | name |
|
|
229
229
|
| messages | ChatModule | id, room_id, sender_id, content, sent_at | room_id, sender_id, sent_at |
|
|
230
230
|
| room_members | ChatModule | id, room_id, user_id, joined_at | room_id, user_id |
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 7. 环境配置
|
|
235
|
+
|
|
236
|
+
| 项目项 | 值 | 说明 |
|
|
237
|
+
|------|----|------|
|
|
238
|
+
| 项目根路径 | `[自动填充]` | 运行 `pwd` 或识别 `.git/.claude` 所在目录 |
|
|
239
|
+
| 代码根路径 | `[自动填充]` | 常见为 `src/`,若无则为项目根 |
|
|
@@ -50,6 +50,21 @@ docs/
|
|
|
50
50
|
| P-001 | API文档 | `docs/project/api.md` | REST API端点 | active |
|
|
51
51
|
| P-002 | 数据库Schema | `docs/project/database.md` | 表结构和ER图 | active |
|
|
52
52
|
|
|
53
|
+
**自动创建规则**:
|
|
54
|
+
```yaml
|
|
55
|
+
project_docs:
|
|
56
|
+
create_if:
|
|
57
|
+
has_api_layer: docs/project/api.md
|
|
58
|
+
has_database: docs/project/database.md
|
|
59
|
+
has_frontend: docs/project/frontend.md
|
|
60
|
+
has_backend: docs/project/backend.md
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**使用方式**:
|
|
64
|
+
- 新增文档必须先登记到注册表(§2.2)
|
|
65
|
+
- 文档开头写明用途、更新时机、信息来源
|
|
66
|
+
- 内容更新以模块变更为触发,不做长期遗漏
|
|
67
|
+
|
|
53
68
|
### 2.3 任务交接文件(Task Handoff)
|
|
54
69
|
|
|
55
70
|
**位置**:`docs/.jvibe/tasks.yaml`
|
|
@@ -146,6 +161,23 @@ planner 分析需求(必要时反问澄清)
|
|
|
146
161
|
...
|
|
147
162
|
```
|
|
148
163
|
|
|
164
|
+
### 3.5 环境隔离与依赖安装
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
env_isolation:
|
|
168
|
+
required: true
|
|
169
|
+
forbid: [base, global]
|
|
170
|
+
allowed:
|
|
171
|
+
- .venv
|
|
172
|
+
- .conda
|
|
173
|
+
install:
|
|
174
|
+
python: "<env>/bin/python -m pip install ..."
|
|
175
|
+
node: "npm ci (project root)"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
- 任何测试或脚本必须使用项目隔离环境,不允许默认 base 环境
|
|
179
|
+
- 环境选择与激活方式写入项目文档(如无相关章节则新增“环境配置”)
|
|
180
|
+
|
|
149
181
|
---
|
|
150
182
|
|
|
151
183
|
## 4. 文档编写规范
|
|
@@ -197,6 +229,14 @@ planner 分析需求(必要时反问澄清)
|
|
|
197
229
|
1. 在注册表(§2.2)添加记录
|
|
198
230
|
2. 在文档开头说明用途和更新时机
|
|
199
231
|
|
|
232
|
+
必须包含项目路径信息:
|
|
233
|
+
```yaml
|
|
234
|
+
project_paths:
|
|
235
|
+
project_root: required
|
|
236
|
+
code_root: required
|
|
237
|
+
source: auto_detected
|
|
238
|
+
```
|
|
239
|
+
|
|
200
240
|
---
|
|
201
241
|
|
|
202
242
|
## 5. 文档同步规则
|