@sk8metal/michi-cli 0.0.7 → 0.0.8
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/CHANGELOG.md +22 -0
- package/README.md +3 -2
- package/dist/scripts/__tests__/create-project.test.d.ts +2 -0
- package/dist/scripts/__tests__/create-project.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/create-project.test.js +247 -0
- package/dist/scripts/__tests__/create-project.test.js.map +1 -0
- package/dist/scripts/__tests__/multi-project-estimate.test.d.ts +2 -0
- package/dist/scripts/__tests__/multi-project-estimate.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/multi-project-estimate.test.js +119 -0
- package/dist/scripts/__tests__/multi-project-estimate.test.js.map +1 -0
- package/dist/scripts/__tests__/setup-existing-project.test.d.ts +2 -0
- package/dist/scripts/__tests__/setup-existing-project.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/setup-existing-project.test.js +67 -0
- package/dist/scripts/__tests__/setup-existing-project.test.js.map +1 -0
- package/dist/scripts/__tests__/setup-interactive.test.d.ts +2 -0
- package/dist/scripts/__tests__/setup-interactive.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/setup-interactive.test.js +160 -0
- package/dist/scripts/__tests__/setup-interactive.test.js.map +1 -0
- package/dist/scripts/config/default-config.json +57 -0
- package/dist/scripts/confluence-sync.d.ts +4 -0
- package/dist/scripts/confluence-sync.d.ts.map +1 -1
- package/dist/scripts/confluence-sync.js +12 -23
- package/dist/scripts/confluence-sync.js.map +1 -1
- package/dist/scripts/create-project.js +198 -137
- package/dist/scripts/create-project.js.map +1 -1
- package/dist/scripts/jira-sync.d.ts.map +1 -1
- package/dist/scripts/jira-sync.js +15 -0
- package/dist/scripts/jira-sync.js.map +1 -1
- package/dist/scripts/list-projects.d.ts.map +1 -1
- package/dist/scripts/list-projects.js +42 -15
- package/dist/scripts/list-projects.js.map +1 -1
- package/dist/scripts/multi-project-estimate.d.ts.map +1 -1
- package/dist/scripts/multi-project-estimate.js +56 -21
- package/dist/scripts/multi-project-estimate.js.map +1 -1
- package/dist/scripts/resource-dashboard.d.ts.map +1 -1
- package/dist/scripts/resource-dashboard.js +74 -17
- package/dist/scripts/resource-dashboard.js.map +1 -1
- package/dist/scripts/setup-existing-project.js +248 -214
- package/dist/scripts/setup-existing-project.js.map +1 -1
- package/dist/scripts/setup-interactive.d.ts +10 -0
- package/dist/scripts/setup-interactive.d.ts.map +1 -0
- package/dist/scripts/setup-interactive.js +413 -0
- package/dist/scripts/setup-interactive.js.map +1 -0
- package/dist/scripts/utils/__tests__/config-validator.test.js +5 -0
- package/dist/scripts/utils/__tests__/config-validator.test.js.map +1 -1
- package/dist/scripts/utils/__tests__/spec-updater.test.d.ts +5 -0
- package/dist/scripts/utils/__tests__/spec-updater.test.d.ts.map +1 -0
- package/dist/scripts/utils/__tests__/spec-updater.test.js +158 -0
- package/dist/scripts/utils/__tests__/spec-updater.test.js.map +1 -0
- package/dist/scripts/utils/confluence-hierarchy.d.ts +2 -1
- package/dist/scripts/utils/confluence-hierarchy.d.ts.map +1 -1
- package/dist/scripts/utils/confluence-hierarchy.js +5 -0
- package/dist/scripts/utils/confluence-hierarchy.js.map +1 -1
- package/dist/scripts/utils/project-finder.d.ts +30 -0
- package/dist/scripts/utils/project-finder.d.ts.map +1 -0
- package/dist/scripts/utils/project-finder.js +147 -0
- package/dist/scripts/utils/project-finder.js.map +1 -0
- package/dist/scripts/utils/spec-updater.d.ts +72 -0
- package/dist/scripts/utils/spec-updater.d.ts.map +1 -0
- package/dist/scripts/utils/spec-updater.js +141 -0
- package/dist/scripts/utils/spec-updater.js.map +1 -0
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/vitest.config.js +8 -6
- package/dist/vitest.config.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/contributing/development.md +37 -0
- package/docs/getting-started/{new-project-setup.md → new-repository-setup.md} +66 -19
- package/docs/getting-started/setup.md +305 -182
- package/docs/guides/customization.md +1 -1
- package/docs/guides/multi-project.md +11 -8
- package/docs/reference/quick-reference.md +2 -2
- package/docs/testing-strategy.md +87 -0
- package/package.json +17 -5
- package/scripts/__tests__/create-project.test.ts +292 -0
- package/scripts/__tests__/multi-project-estimate.test.ts +145 -0
- package/scripts/__tests__/setup-existing-project.test.ts +79 -0
- package/scripts/__tests__/setup-interactive.test.ts +199 -0
- package/scripts/confluence-sync.ts +17 -29
- package/scripts/copy-static-assets.js +50 -0
- package/scripts/create-project.ts +219 -156
- package/scripts/jira-sync.ts +16 -1
- package/scripts/list-projects.ts +51 -24
- package/scripts/multi-project-estimate.ts +58 -22
- package/scripts/resource-dashboard.ts +91 -26
- package/scripts/setup-existing-project.ts +264 -223
- package/scripts/setup-existing.sh +29 -22
- package/scripts/setup-interactive.ts +565 -0
- package/scripts/utils/__tests__/config-validator.test.ts +6 -0
- package/scripts/utils/__tests__/spec-updater.test.ts +220 -0
- package/scripts/utils/confluence-hierarchy.ts +7 -1
- package/scripts/utils/project-finder.ts +184 -0
- package/scripts/utils/spec-updater.ts +212 -0
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { cpSync, existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
14
14
|
import { resolve, join, basename } from 'path';
|
|
15
15
|
import { execSync } from 'child_process';
|
|
16
|
+
import { findRepositoryRoot } from './utils/project-finder.js';
|
|
16
17
|
|
|
17
18
|
interface SetupConfig {
|
|
18
19
|
michiPath: string; // Michiリポジトリのパス
|
|
@@ -67,187 +68,221 @@ async function setupExistingProject(config: SetupConfig): Promise<void> {
|
|
|
67
68
|
console.log(` Michiパス: ${config.michiPath}`);
|
|
68
69
|
console.log('');
|
|
69
70
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
if (!existsSync('.cursor/commands/kiro')) {
|
|
73
|
-
console.log(' Installing cc-sdd...');
|
|
74
|
-
execSync('npx cc-sdd@latest --cursor --lang ja --yes', { stdio: 'inherit' });
|
|
75
|
-
console.log(' ✅ cc-sdd installed');
|
|
76
|
-
} else {
|
|
77
|
-
console.log(' ✅ cc-sdd already installed');
|
|
78
|
-
}
|
|
71
|
+
// リポジトリルートを検出
|
|
72
|
+
const repoRoot = findRepositoryRoot(currentDir);
|
|
79
73
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
mkdirSync('.kiro/steering', { recursive: true });
|
|
84
|
-
mkdirSync('.kiro/specs', { recursive: true });
|
|
85
|
-
console.log(' ✅ Directory structure created');
|
|
74
|
+
// projects/{project-id}/配下にプロジェクトを作成
|
|
75
|
+
const projectsDir = join(repoRoot, 'projects');
|
|
76
|
+
const projectDir = join(projectsDir, projectId);
|
|
86
77
|
|
|
87
|
-
|
|
88
|
-
console.log(
|
|
78
|
+
console.log(`📁 リポジトリルート: ${repoRoot}`);
|
|
79
|
+
console.log(`📁 プロジェクトディレクトリ: ${projectDir}`);
|
|
80
|
+
console.log('');
|
|
81
|
+
|
|
82
|
+
// projects/ディレクトリとプロジェクトディレクトリを作成
|
|
83
|
+
if (!existsSync(projectsDir)) {
|
|
84
|
+
mkdirSync(projectsDir, { recursive: true });
|
|
85
|
+
console.log(` ✅ Created: ${projectsDir}`);
|
|
86
|
+
}
|
|
87
|
+
if (!existsSync(projectDir)) {
|
|
88
|
+
mkdirSync(projectDir, { recursive: true });
|
|
89
|
+
console.log(` ✅ Created: ${projectDir}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 元の作業ディレクトリを保存
|
|
93
|
+
const originalCwd = process.cwd();
|
|
89
94
|
|
|
90
|
-
// GitHub URLを取得(既存リポジトリから)
|
|
91
|
-
let repoUrl = '';
|
|
92
95
|
try {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
// プロジェクトディレクトリに移動
|
|
97
|
+
process.chdir(projectDir);
|
|
98
|
+
|
|
99
|
+
// Step 1: cc-sdd導入確認
|
|
100
|
+
console.log('\n📦 Step 1: Checking cc-sdd installation...');
|
|
101
|
+
if (!existsSync('.cursor/commands/kiro')) {
|
|
102
|
+
console.log(' Installing cc-sdd...');
|
|
103
|
+
execSync('npx cc-sdd@latest --cursor --lang ja --yes', { stdio: 'inherit' });
|
|
104
|
+
console.log(' ✅ cc-sdd installed');
|
|
105
|
+
} else {
|
|
106
|
+
console.log(' ✅ cc-sdd already installed');
|
|
97
107
|
}
|
|
98
|
-
} catch {
|
|
99
|
-
repoUrl = `https://github.com/org/${projectId}`;
|
|
100
|
-
}
|
|
101
108
|
|
|
102
|
-
|
|
109
|
+
// Step 2: .kiro ディレクトリ作成
|
|
110
|
+
console.log('\n📁 Step 2: Creating .kiro directory structure...');
|
|
111
|
+
mkdirSync('.kiro/settings/templates', { recursive: true });
|
|
112
|
+
mkdirSync('.kiro/steering', { recursive: true });
|
|
113
|
+
mkdirSync('.kiro/specs', { recursive: true });
|
|
114
|
+
console.log(' ✅ Directory structure created');
|
|
115
|
+
|
|
116
|
+
// Step 3: プロジェクトメタデータ作成
|
|
117
|
+
console.log('\n📝 Step 3: Creating project metadata...');
|
|
118
|
+
|
|
119
|
+
// GitHub URLを取得(既存リポジトリから)
|
|
120
|
+
let repoUrl = '';
|
|
121
|
+
try {
|
|
122
|
+
repoUrl = execSync('git config --get remote.origin.url', { encoding: 'utf-8', cwd: repoRoot }).trim();
|
|
123
|
+
// SSH形式をHTTPS形式に変換
|
|
124
|
+
if (repoUrl.startsWith('git@github.com:')) {
|
|
125
|
+
repoUrl = repoUrl.replace('git@github.com:', 'https://github.com/').replace('.git', '');
|
|
126
|
+
}
|
|
127
|
+
} catch {
|
|
128
|
+
repoUrl = `https://github.com/org/${projectId}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const labels = config.labels || (() => {
|
|
103
132
|
// プロジェクトIDからプロジェクトラベル生成
|
|
104
|
-
|
|
105
|
-
|
|
133
|
+
const projectLabel = projectId.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
134
|
+
const labelSet = new Set([`project:${projectLabel}`]);
|
|
106
135
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
136
|
+
// ハイフンが存在する場合のみサービスラベルを生成
|
|
137
|
+
if (projectId.includes('-')) {
|
|
138
|
+
const parts = projectId.split('-');
|
|
139
|
+
const servicePart = parts[parts.length - 1];
|
|
140
|
+
const serviceLabel = servicePart.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
112
141
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
142
|
+
// サービスラベルがプロジェクトラベルと異なる場合のみ追加
|
|
143
|
+
if (serviceLabel !== projectLabel) {
|
|
144
|
+
labelSet.add(`service:${serviceLabel}`);
|
|
145
|
+
}
|
|
116
146
|
}
|
|
117
|
-
}
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
'
|
|
142
|
-
'
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
return Array.from(labelSet);
|
|
149
|
+
})();
|
|
150
|
+
|
|
151
|
+
const projectJson = {
|
|
152
|
+
projectId,
|
|
153
|
+
projectName: config.projectName,
|
|
154
|
+
jiraProjectKey: config.jiraKey,
|
|
155
|
+
confluenceLabels: labels,
|
|
156
|
+
status: 'active',
|
|
157
|
+
team: [],
|
|
158
|
+
stakeholders: ['@企画', '@部長'],
|
|
159
|
+
repository: repoUrl,
|
|
160
|
+
description: `${config.projectName}の開発`
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
writeFileSync('.kiro/project.json', JSON.stringify(projectJson, null, 2));
|
|
164
|
+
console.log(' ✅ project.json created');
|
|
165
|
+
|
|
166
|
+
// Step 4: Michiから共通ルールをコピー
|
|
167
|
+
console.log('\n📋 Step 4: Copying common rules from Michi...');
|
|
168
|
+
|
|
169
|
+
// ディレクトリを事前に作成
|
|
170
|
+
mkdirSync(join(projectDir, '.cursor/rules'), { recursive: true });
|
|
171
|
+
mkdirSync(join(projectDir, '.cursor/commands/kiro'), { recursive: true });
|
|
172
|
+
|
|
173
|
+
const rulesToCopy = [
|
|
174
|
+
'multi-project.mdc',
|
|
175
|
+
'github-ssot.mdc',
|
|
176
|
+
'atlassian-mcp.mdc'
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
for (const rule of rulesToCopy) {
|
|
180
|
+
const src = join(config.michiPath, '.cursor/rules', rule);
|
|
181
|
+
const dest = join(projectDir, '.cursor/rules', rule);
|
|
182
|
+
if (existsSync(src)) {
|
|
183
|
+
cpSync(src, dest);
|
|
184
|
+
console.log(` ✅ ${rule}`);
|
|
185
|
+
} else {
|
|
186
|
+
console.log(` ⚠️ ${rule} not found in Michi`);
|
|
187
|
+
}
|
|
154
188
|
}
|
|
155
|
-
}
|
|
156
189
|
|
|
157
|
-
|
|
158
|
-
|
|
190
|
+
// Step 5: カスタムコマンドをコピー
|
|
191
|
+
console.log('\n🔧 Step 5: Copying custom commands...');
|
|
159
192
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
193
|
+
const commandsToCopy = [
|
|
194
|
+
'confluence-sync.md',
|
|
195
|
+
'project-switch.md'
|
|
196
|
+
];
|
|
164
197
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
198
|
+
for (const cmd of commandsToCopy) {
|
|
199
|
+
const src = join(config.michiPath, '.cursor/commands/kiro', cmd);
|
|
200
|
+
const dest = join(projectDir, '.cursor/commands/kiro', cmd);
|
|
201
|
+
if (existsSync(src)) {
|
|
202
|
+
cpSync(src, dest);
|
|
203
|
+
console.log(` ✅ ${cmd}`);
|
|
204
|
+
}
|
|
171
205
|
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Step 6: Steeringテンプレートをコピー
|
|
175
|
-
console.log('\n📚 Step 6: Copying steering templates...');
|
|
176
206
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
cpSync(steeringDir, '.kiro/steering', { recursive: true });
|
|
180
|
-
console.log(' ✅ product.md, tech.md, structure.md');
|
|
181
|
-
}
|
|
207
|
+
// Step 6: Steeringテンプレートをコピー
|
|
208
|
+
console.log('\n📚 Step 6: Copying steering templates...');
|
|
182
209
|
|
|
183
|
-
|
|
184
|
-
|
|
210
|
+
const steeringDir = join(config.michiPath, '.kiro/steering');
|
|
211
|
+
if (existsSync(steeringDir)) {
|
|
212
|
+
cpSync(steeringDir, join(projectDir, '.kiro/steering'), { recursive: true });
|
|
213
|
+
console.log(' ✅ product.md, tech.md, structure.md');
|
|
214
|
+
}
|
|
185
215
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
cpSync(templatesDir, '.kiro/settings/templates', { recursive: true });
|
|
189
|
-
console.log(' ✅ requirements.md, design.md, tasks.md');
|
|
190
|
-
}
|
|
216
|
+
// Step 7: テンプレートをコピー
|
|
217
|
+
console.log('\n📄 Step 7: Copying spec templates...');
|
|
191
218
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
console.log(' 📋 使用方法:');
|
|
197
|
-
console.log(' npx @michi/cli jira:sync <feature>');
|
|
198
|
-
console.log(' npx @michi/cli confluence:sync <feature> requirements');
|
|
199
|
-
console.log(' npx @michi/cli phase:run <feature> tasks');
|
|
200
|
-
console.log('');
|
|
201
|
-
console.log(' または、グローバルインストール:');
|
|
202
|
-
console.log(' npm install -g @michi/cli');
|
|
203
|
-
console.log(' michi jira:sync <feature>');
|
|
204
|
-
|
|
205
|
-
// Step 9: package.json と tsconfig.json をコピー
|
|
206
|
-
console.log('\n📦 Step 9: Setting up package.json and TypeScript...');
|
|
207
|
-
|
|
208
|
-
// 既存の package.json があるかチェック
|
|
209
|
-
const hasPackageJson = existsSync('package.json');
|
|
210
|
-
|
|
211
|
-
if (!hasPackageJson) {
|
|
212
|
-
// package.json がない場合はコピー
|
|
213
|
-
const src = join(config.michiPath, 'package.json');
|
|
214
|
-
if (existsSync(src)) {
|
|
215
|
-
cpSync(src, 'package.json');
|
|
216
|
-
console.log(' ✅ package.json created');
|
|
219
|
+
const templatesDir = join(config.michiPath, '.kiro/settings/templates');
|
|
220
|
+
if (existsSync(templatesDir)) {
|
|
221
|
+
cpSync(templatesDir, join(projectDir, '.kiro/settings/templates'), { recursive: true });
|
|
222
|
+
console.log(' ✅ requirements.md, design.md, tasks.md');
|
|
217
223
|
}
|
|
218
|
-
|
|
219
|
-
//
|
|
220
|
-
console.log('
|
|
221
|
-
console.log('
|
|
224
|
+
|
|
225
|
+
// Step 8: CLIツールのセットアップ案内
|
|
226
|
+
console.log('\n⚙️ Step 8: Setting up Michi CLI...');
|
|
227
|
+
console.log(' ✅ Michi CLI setup complete!');
|
|
222
228
|
console.log('');
|
|
223
|
-
console.log('
|
|
224
|
-
console.log('
|
|
225
|
-
console.log('
|
|
226
|
-
console.log('
|
|
227
|
-
console.log(' "validate:phase": "npx @michi/cli validate:phase",');
|
|
228
|
-
console.log(' "preflight": "npx @michi/cli preflight",');
|
|
229
|
-
console.log(' "project:list": "npx @michi/cli project:list",');
|
|
230
|
-
console.log(' "project:dashboard": "npx @michi/cli project:dashboard",');
|
|
231
|
-
console.log(' "workflow:run": "npx @michi/cli workflow:run"');
|
|
232
|
-
console.log(' }');
|
|
229
|
+
console.log(' 📋 使用方法:');
|
|
230
|
+
console.log(' npx @sk8metal/michi-cli jira:sync <feature>');
|
|
231
|
+
console.log(' npx @sk8metal/michi-cli confluence:sync <feature> requirements');
|
|
232
|
+
console.log(' npx @sk8metal/michi-cli phase:run <feature> tasks');
|
|
233
233
|
console.log('');
|
|
234
|
-
|
|
234
|
+
console.log(' または、グローバルインストール:');
|
|
235
|
+
console.log(' npm install -g @sk8metal/michi-cli');
|
|
236
|
+
console.log(' michi jira:sync <feature>');
|
|
237
|
+
|
|
238
|
+
// Step 9: package.json と tsconfig.json をリポジトリルートにコピー
|
|
239
|
+
console.log('\n📦 Step 9: Setting up package.json and TypeScript...');
|
|
240
|
+
|
|
241
|
+
// 既存の package.json があるかチェック(リポジトリルート)
|
|
242
|
+
const hasPackageJson = existsSync(join(repoRoot, 'package.json'));
|
|
243
|
+
|
|
244
|
+
if (!hasPackageJson) {
|
|
245
|
+
// package.json がない場合はリポジトリルートにコピー
|
|
246
|
+
const src = join(config.michiPath, 'package.json');
|
|
247
|
+
const dest = join(repoRoot, 'package.json');
|
|
248
|
+
if (existsSync(src)) {
|
|
249
|
+
cpSync(src, dest);
|
|
250
|
+
console.log(' ✅ package.json created (in repository root)');
|
|
251
|
+
}
|
|
252
|
+
} else {
|
|
253
|
+
// 既存の package.json にスクリプトを追加
|
|
254
|
+
console.log(' ℹ️ Existing package.json found');
|
|
255
|
+
console.log(' 📝 手動で以下のスクリプトを追加してください:');
|
|
256
|
+
console.log('');
|
|
257
|
+
console.log(' "scripts": {');
|
|
258
|
+
console.log(' "jira:sync": "npx @sk8metal/michi-cli jira:sync",');
|
|
259
|
+
console.log(' "confluence:sync": "npx @sk8metal/michi-cli confluence:sync",');
|
|
260
|
+
console.log(' "phase:run": "npx @sk8metal/michi-cli phase:run",');
|
|
261
|
+
console.log(' "validate:phase": "npx @sk8metal/michi-cli validate:phase",');
|
|
262
|
+
console.log(' "preflight": "npx @sk8metal/michi-cli preflight",');
|
|
263
|
+
console.log(' "project:list": "npx @sk8metal/michi-cli project:list",');
|
|
264
|
+
console.log(' "project:dashboard": "npx @sk8metal/michi-cli project:dashboard",');
|
|
265
|
+
console.log(' "workflow:run": "npx @sk8metal/michi-cli workflow:run"');
|
|
266
|
+
console.log(' }');
|
|
267
|
+
console.log('');
|
|
268
|
+
}
|
|
235
269
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
270
|
+
// tsconfig.json をリポジトリルートにコピー
|
|
271
|
+
if (!existsSync(join(repoRoot, 'tsconfig.json'))) {
|
|
272
|
+
const src = join(config.michiPath, 'tsconfig.json');
|
|
273
|
+
const dest = join(repoRoot, 'tsconfig.json');
|
|
274
|
+
if (existsSync(src)) {
|
|
275
|
+
cpSync(src, dest);
|
|
276
|
+
console.log(' ✅ tsconfig.json created (in repository root)');
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
console.log(' ℹ️ Existing tsconfig.json found (kept)');
|
|
242
280
|
}
|
|
243
|
-
} else {
|
|
244
|
-
console.log(' ℹ️ Existing tsconfig.json found (kept)');
|
|
245
|
-
}
|
|
246
281
|
|
|
247
|
-
|
|
248
|
-
|
|
282
|
+
// Step 10: .env テンプレート作成(プロジェクトディレクトリに)
|
|
283
|
+
console.log('\n🔐 Step 10: Creating .env template...');
|
|
249
284
|
|
|
250
|
-
|
|
285
|
+
const envTemplate = `# Atlassian設定(MCP + REST API共通)
|
|
251
286
|
ATLASSIAN_URL=https://your-domain.atlassian.net
|
|
252
287
|
ATLASSIAN_EMAIL=your-email@company.com
|
|
253
288
|
ATLASSIAN_API_TOKEN=your-token-here
|
|
@@ -266,22 +301,22 @@ CONFLUENCE_RELEASE_SPACE=RELEASE
|
|
|
266
301
|
JIRA_PROJECT_KEYS=${config.jiraKey}
|
|
267
302
|
`;
|
|
268
303
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
304
|
+
if (!existsSync(join(projectDir, '.env'))) {
|
|
305
|
+
writeFileSync(join(projectDir, '.env'), envTemplate);
|
|
306
|
+
console.log(' ✅ .env template created');
|
|
307
|
+
} else {
|
|
308
|
+
console.log(' ℹ️ .env already exists (kept)');
|
|
309
|
+
}
|
|
275
310
|
|
|
276
|
-
|
|
277
|
-
|
|
311
|
+
// Step 11: README.md を更新(オプション、プロジェクトディレクトリに)
|
|
312
|
+
console.log('\n📖 Step 11: Updating documentation...');
|
|
278
313
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
314
|
+
const readmePath = join(projectDir, 'README.md');
|
|
315
|
+
if (existsSync(readmePath)) {
|
|
316
|
+
const currentReadme = readFileSync(readmePath, 'utf-8');
|
|
282
317
|
|
|
283
|
-
|
|
284
|
-
|
|
318
|
+
// Michiワークフロー情報を追加
|
|
319
|
+
const workflowSection = `
|
|
285
320
|
|
|
286
321
|
## AI開発ワークフロー
|
|
287
322
|
|
|
@@ -308,68 +343,74 @@ npm run github:create-pr <branch> # PR作成
|
|
|
308
343
|
詳細: [Michi Documentation](https://github.com/sk8metalme/michi)
|
|
309
344
|
`;
|
|
310
345
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
346
|
+
if (!currentReadme.includes('AI開発ワークフロー')) {
|
|
347
|
+
writeFileSync(readmePath, currentReadme + workflowSection);
|
|
348
|
+
console.log(' ✅ README.md updated');
|
|
349
|
+
} else {
|
|
350
|
+
console.log(' ℹ️ README.md already has workflow section');
|
|
351
|
+
}
|
|
316
352
|
}
|
|
317
|
-
}
|
|
318
353
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
354
|
+
// Step 12: .gitignore 更新(リポジトリルートに)
|
|
355
|
+
console.log('\n🚫 Step 12: Updating .gitignore...');
|
|
356
|
+
|
|
357
|
+
const gitignoreEntries = [
|
|
358
|
+
'# AI Development Workflow',
|
|
359
|
+
'node_modules/',
|
|
360
|
+
'.env',
|
|
361
|
+
'.env.local',
|
|
362
|
+
'dist/',
|
|
363
|
+
'*.log'
|
|
364
|
+
];
|
|
365
|
+
|
|
366
|
+
const gitignorePath = join(repoRoot, '.gitignore');
|
|
367
|
+
let gitignore = '';
|
|
368
|
+
if (existsSync(gitignorePath)) {
|
|
369
|
+
gitignore = readFileSync(gitignorePath, 'utf-8');
|
|
370
|
+
}
|
|
335
371
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
372
|
+
let updated = false;
|
|
373
|
+
for (const entry of gitignoreEntries) {
|
|
374
|
+
if (!gitignore.includes(entry)) {
|
|
375
|
+
gitignore += `\n${entry}`;
|
|
376
|
+
updated = true;
|
|
377
|
+
}
|
|
341
378
|
}
|
|
342
|
-
}
|
|
343
379
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
380
|
+
if (updated) {
|
|
381
|
+
writeFileSync(gitignorePath, gitignore);
|
|
382
|
+
console.log(' ✅ .gitignore updated (in repository root)');
|
|
383
|
+
} else {
|
|
384
|
+
console.log(' ℹ️ .gitignore already up to date');
|
|
385
|
+
}
|
|
350
386
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
387
|
+
// 完了メッセージ
|
|
388
|
+
console.log('\n');
|
|
389
|
+
console.log('🎉 セットアップ完了!');
|
|
390
|
+
console.log('');
|
|
391
|
+
console.log('次のステップ:');
|
|
392
|
+
console.log(` 1. cd ${projectDir}`);
|
|
393
|
+
console.log(' 2. .env ファイルを編集して認証情報を設定');
|
|
394
|
+
console.log(' 3. package.json が既存の場合、スクリプトを手動追加');
|
|
395
|
+
console.log(' 4. npm install で依存関係をインストール(リポジトリルートで実行)');
|
|
396
|
+
console.log(' 5. jj commit でセットアップをコミット');
|
|
397
|
+
console.log(' 6. Cursor で開く: cursor .');
|
|
398
|
+
console.log(' 7. /kiro:spec-init <機能説明> で開発開始');
|
|
399
|
+
console.log('');
|
|
400
|
+
console.log('作成されたファイル:');
|
|
401
|
+
console.log(` - ${projectDir}/.kiro/project.json`);
|
|
402
|
+
console.log(` - ${projectDir}/.cursor/rules/ (3ファイル)`);
|
|
403
|
+
console.log(` - ${projectDir}/.cursor/commands/kiro/ (2ファイル)`);
|
|
404
|
+
console.log(` - ${projectDir}/.kiro/steering/ (3ファイル)`);
|
|
405
|
+
console.log(` - ${projectDir}/.kiro/settings/templates/ (3ファイル)`);
|
|
406
|
+
console.log(` - ${repoRoot}/package.json (新規の場合)`);
|
|
407
|
+
console.log(` - ${repoRoot}/tsconfig.json (新規の場合)`);
|
|
408
|
+
console.log(` - ${projectDir}/.env (テンプレート)`);
|
|
409
|
+
|
|
410
|
+
} finally {
|
|
411
|
+
// 元の作業ディレクトリに戻る
|
|
412
|
+
process.chdir(originalCwd);
|
|
413
|
+
}
|
|
373
414
|
}
|
|
374
415
|
|
|
375
416
|
// 実行
|
|
@@ -87,28 +87,35 @@ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━
|
|
|
87
87
|
echo -e "${YELLOW}📋 次のステップ(重要)${NC}"
|
|
88
88
|
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
89
89
|
echo ""
|
|
90
|
-
echo -e "${YELLOW}Step 1:
|
|
91
|
-
echo "
|
|
92
|
-
echo ""
|
|
93
|
-
echo "
|
|
94
|
-
echo "
|
|
95
|
-
echo "
|
|
96
|
-
echo "
|
|
97
|
-
echo "
|
|
98
|
-
echo "
|
|
99
|
-
echo ""
|
|
100
|
-
echo "
|
|
101
|
-
echo "
|
|
102
|
-
echo "
|
|
103
|
-
echo "
|
|
104
|
-
echo "
|
|
105
|
-
echo "
|
|
106
|
-
echo ""
|
|
107
|
-
echo "
|
|
108
|
-
echo "
|
|
109
|
-
echo "
|
|
110
|
-
echo "
|
|
111
|
-
echo "
|
|
90
|
+
echo -e "${YELLOW}Step 1: 認証情報の設定${NC}"
|
|
91
|
+
echo ""
|
|
92
|
+
echo " ${BLUE}方法A: 対話的設定ツールを使用(推奨)${NC}"
|
|
93
|
+
echo " ${GREEN}$ npm run setup:interactive${NC}"
|
|
94
|
+
echo " または"
|
|
95
|
+
echo " ${GREEN}$ npx tsx ${MICHI_PATH}/scripts/setup-interactive.ts${NC}"
|
|
96
|
+
echo ""
|
|
97
|
+
echo " ${BLUE}方法B: 手動で.envファイルを編集${NC}"
|
|
98
|
+
echo " ファイル: $(pwd)/.env"
|
|
99
|
+
echo ""
|
|
100
|
+
echo " ${BLUE}🔑 Atlassian API トークンの取得:${NC}"
|
|
101
|
+
echo " 1. Atlassian アカウントにログイン"
|
|
102
|
+
echo " 2. https://id.atlassian.com/manage-profile/security/api-tokens にアクセス"
|
|
103
|
+
echo " 3. 「APIトークンを作成」をクリック"
|
|
104
|
+
echo " 4. ラベルを入力(例: Michi Workflow)して作成"
|
|
105
|
+
echo " 5. 生成されたトークンをコピー(※一度しか表示されません)"
|
|
106
|
+
echo ""
|
|
107
|
+
echo " ${BLUE}🔑 GitHub Personal Access Token の取得:${NC}"
|
|
108
|
+
echo " 1. GitHub にログイン"
|
|
109
|
+
echo " 2. https://github.com/settings/tokens にアクセス"
|
|
110
|
+
echo " 3. 「Generate new token (classic)」をクリック"
|
|
111
|
+
echo " 4. スコープを選択: repo, workflow, read:org"
|
|
112
|
+
echo " 5. 「Generate token」をクリックしてトークンをコピー"
|
|
113
|
+
echo ""
|
|
114
|
+
echo " ${GREEN}編集例:${NC}"
|
|
115
|
+
echo " ATLASSIAN_URL=https://your-domain.atlassian.net"
|
|
116
|
+
echo " ATLASSIAN_EMAIL=your-email@company.com"
|
|
117
|
+
echo " ATLASSIAN_API_TOKEN=<上記で取得したトークン>"
|
|
118
|
+
echo " GITHUB_TOKEN=ghp_xxxxxxxxxxxxx"
|
|
112
119
|
echo ""
|
|
113
120
|
echo -e "${YELLOW}Step 2: 依存パッケージのインストール${NC}"
|
|
114
121
|
echo " ${GREEN}$ npm install${NC}"
|