@sk8metal/michi-cli 0.4.0 → 0.7.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/CHANGELOG.md +162 -1
- package/README.md +2 -1
- package/dist/scripts/config/config-schema.d.ts +87 -0
- package/dist/scripts/config/config-schema.d.ts.map +1 -1
- package/dist/scripts/config/config-schema.js +81 -0
- package/dist/scripts/config/config-schema.js.map +1 -1
- package/dist/scripts/confluence-sync.d.ts.map +1 -1
- package/dist/scripts/confluence-sync.js +15 -2
- package/dist/scripts/confluence-sync.js.map +1 -1
- package/dist/scripts/github-actions-client.d.ts +79 -0
- package/dist/scripts/github-actions-client.d.ts.map +1 -0
- package/dist/scripts/github-actions-client.js +182 -0
- package/dist/scripts/github-actions-client.js.map +1 -0
- package/dist/scripts/health-check-service.d.ts +46 -0
- package/dist/scripts/health-check-service.d.ts.map +1 -0
- package/dist/scripts/health-check-service.js +114 -0
- package/dist/scripts/health-check-service.js.map +1 -0
- package/dist/scripts/markdown-to-confluence.d.ts.map +1 -1
- package/dist/scripts/markdown-to-confluence.js +25 -3
- package/dist/scripts/markdown-to-confluence.js.map +1 -1
- package/dist/scripts/mermaid-converter.d.ts +24 -0
- package/dist/scripts/mermaid-converter.d.ts.map +1 -0
- package/dist/scripts/mermaid-converter.js +49 -0
- package/dist/scripts/mermaid-converter.js.map +1 -0
- package/dist/scripts/pr-automation.d.ts.map +1 -1
- package/dist/scripts/pr-automation.js +11 -3
- package/dist/scripts/pr-automation.js.map +1 -1
- package/dist/scripts/spec-impl-workflow.d.ts.map +1 -1
- package/dist/scripts/spec-impl-workflow.js +22 -6
- package/dist/scripts/spec-impl-workflow.js.map +1 -1
- package/dist/scripts/template/multi-repo-renderer.d.ts +67 -0
- package/dist/scripts/template/multi-repo-renderer.d.ts.map +1 -0
- package/dist/scripts/template/multi-repo-renderer.js +123 -0
- package/dist/scripts/template/multi-repo-renderer.js.map +1 -0
- package/dist/scripts/template/renderer.d.ts +4 -0
- package/dist/scripts/template/renderer.d.ts.map +1 -1
- package/dist/scripts/template/renderer.js.map +1 -1
- package/dist/scripts/test-execution-generator.d.ts.map +1 -1
- package/dist/scripts/test-execution-generator.js +94 -11
- package/dist/scripts/test-execution-generator.js.map +1 -1
- package/dist/scripts/test-script-runner.d.ts +33 -0
- package/dist/scripts/test-script-runner.d.ts.map +1 -0
- package/dist/scripts/test-script-runner.js +77 -0
- package/dist/scripts/test-script-runner.js.map +1 -0
- package/dist/scripts/utils/config-loader.d.ts +31 -5
- package/dist/scripts/utils/config-loader.d.ts.map +1 -1
- package/dist/scripts/utils/config-loader.js +363 -50
- package/dist/scripts/utils/config-loader.js.map +1 -1
- package/dist/scripts/utils/env-config.d.ts +1 -1
- package/dist/scripts/utils/env-config.d.ts.map +1 -1
- package/dist/scripts/utils/env-config.js +2 -14
- package/dist/scripts/utils/env-config.js.map +1 -1
- package/dist/scripts/utils/multi-repo-validator.d.ts +30 -0
- package/dist/scripts/utils/multi-repo-validator.d.ts.map +1 -0
- package/dist/scripts/utils/multi-repo-validator.js +105 -0
- package/dist/scripts/utils/multi-repo-validator.js.map +1 -0
- package/dist/scripts/utils/project-meta.d.ts +9 -0
- package/dist/scripts/utils/project-meta.d.ts.map +1 -1
- package/dist/scripts/utils/project-meta.js +22 -0
- package/dist/scripts/utils/project-meta.js.map +1 -1
- package/dist/scripts/utils/security-validator.d.ts +55 -0
- package/dist/scripts/utils/security-validator.d.ts.map +1 -0
- package/dist/scripts/utils/security-validator.js +232 -0
- package/dist/scripts/utils/security-validator.js.map +1 -0
- package/dist/scripts/utils/spec-archiver.d.ts +38 -0
- package/dist/scripts/utils/spec-archiver.d.ts.map +1 -0
- package/dist/scripts/utils/spec-archiver.js +210 -0
- package/dist/scripts/utils/spec-archiver.js.map +1 -0
- package/dist/scripts/utils/spec-updater.d.ts +4 -0
- package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
- package/dist/scripts/utils/spec-updater.js.map +1 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +303 -17
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/config-validate.d.ts +9 -0
- package/dist/src/commands/config-validate.d.ts.map +1 -0
- package/dist/src/commands/config-validate.js +90 -0
- package/dist/src/commands/config-validate.js.map +1 -0
- package/dist/src/commands/init.d.ts +1 -0
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +29 -6
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/migrate.d.ts +25 -0
- package/dist/src/commands/migrate.d.ts.map +1 -0
- package/dist/src/commands/migrate.js +341 -0
- package/dist/src/commands/migrate.js.map +1 -0
- package/dist/src/commands/multi-repo-add-repo.d.ts +26 -0
- package/dist/src/commands/multi-repo-add-repo.d.ts.map +1 -0
- package/dist/src/commands/multi-repo-add-repo.js +56 -0
- package/dist/src/commands/multi-repo-add-repo.js.map +1 -0
- package/dist/src/commands/multi-repo-ci-status.d.ts +46 -0
- package/dist/src/commands/multi-repo-ci-status.d.ts.map +1 -0
- package/dist/src/commands/multi-repo-ci-status.js +285 -0
- package/dist/src/commands/multi-repo-ci-status.js.map +1 -0
- package/dist/src/commands/multi-repo-confluence-sync.d.ts +45 -0
- package/dist/src/commands/multi-repo-confluence-sync.d.ts.map +1 -0
- package/dist/src/commands/multi-repo-confluence-sync.js +135 -0
- package/dist/src/commands/multi-repo-confluence-sync.js.map +1 -0
- package/dist/src/commands/multi-repo-init.d.ts +26 -0
- package/dist/src/commands/multi-repo-init.d.ts.map +1 -0
- package/dist/src/commands/multi-repo-init.js +101 -0
- package/dist/src/commands/multi-repo-init.js.map +1 -0
- package/dist/src/commands/multi-repo-list.d.ts +28 -0
- package/dist/src/commands/multi-repo-list.d.ts.map +1 -0
- package/dist/src/commands/multi-repo-list.js +38 -0
- package/dist/src/commands/multi-repo-list.js.map +1 -0
- package/dist/src/commands/multi-repo-test.d.ts +56 -0
- package/dist/src/commands/multi-repo-test.d.ts.map +1 -0
- package/dist/src/commands/multi-repo-test.js +70 -0
- package/dist/src/commands/multi-repo-test.js.map +1 -0
- package/dist/src/commands/setup-existing.d.ts.map +1 -1
- package/dist/src/commands/setup-existing.js +0 -1
- package/dist/src/commands/setup-existing.js.map +1 -1
- package/dist/src/commands/spec-archive.d.ts +17 -0
- package/dist/src/commands/spec-archive.d.ts.map +1 -0
- package/dist/src/commands/spec-archive.js +40 -0
- package/dist/src/commands/spec-archive.js.map +1 -0
- package/dist/src/commands/spec-list.d.ts +15 -0
- package/dist/src/commands/spec-list.d.ts.map +1 -0
- package/dist/src/commands/spec-list.js +55 -0
- package/dist/src/commands/spec-list.js.map +1 -0
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/vitest.config.js +32 -8
- package/dist/vitest.config.js.map +1 -1
- package/docs/michi-development/design/config-unification.md +4789 -0
- package/docs/user-guide/getting-started/github-token-setup.md +2 -1
- package/docs/user-guide/getting-started/new-repository-setup.md +1 -1
- package/docs/user-guide/getting-started/quick-start.md +1 -1
- package/docs/user-guide/getting-started/setup.md +4 -11
- package/docs/user-guide/guides/multi-repo-guide.md +591 -0
- package/docs/user-guide/guides/multi-repo-migration-guide.md +516 -0
- package/docs/user-guide/hands-on/claude-agent-setup.md +2 -2
- package/docs/user-guide/hands-on/claude-setup.md +2 -2
- package/docs/user-guide/hands-on/cursor-setup.md +2 -2
- package/docs/user-guide/hands-on/workflow-walkthrough.md +4 -1
- package/docs/user-guide/reference/multi-repo-api.md +771 -0
- package/docs/user-guide/reference/quick-reference.md +22 -37
- package/env.example +1 -1
- package/package.json +2 -5
- package/scripts/__tests__/config-loader-multi-repo.test.ts +342 -0
- package/scripts/__tests__/github-actions-client.test.ts +543 -0
- package/scripts/__tests__/health-check-service.test.ts +142 -0
- package/scripts/__tests__/markdown-to-confluence.test.ts +262 -0
- package/scripts/__tests__/mermaid-converter.test.ts +236 -0
- package/scripts/__tests__/multi-repo-config-schema.test.ts +335 -0
- package/scripts/__tests__/multi-repo-validator.test.ts +524 -0
- package/scripts/__tests__/spec-archiver.test.ts +512 -0
- package/scripts/__tests__/spec-impl-workflow.test.ts +5 -2
- package/scripts/__tests__/test-script-runner.test.ts +217 -0
- package/scripts/config/config-schema.ts +104 -0
- package/scripts/confluence-sync.ts +16 -2
- package/scripts/github-actions-client.ts +258 -0
- package/scripts/health-check-service.ts +171 -0
- package/scripts/markdown-to-confluence.ts +37 -6
- package/scripts/mermaid-converter.ts +56 -0
- package/scripts/pr-automation.ts +15 -5
- package/scripts/spec-impl-workflow.ts +22 -6
- package/scripts/template/__tests__/multi-repo-renderer.test.ts +261 -0
- package/scripts/template/multi-repo-renderer.ts +172 -0
- package/scripts/template/renderer.ts +5 -0
- package/scripts/test-execution-generator.ts +104 -11
- package/scripts/test-script-runner.ts +130 -0
- package/scripts/utils/__tests__/config-loader.test.ts +149 -0
- package/scripts/utils/__tests__/config-validator.test.ts +106 -6
- package/scripts/utils/__tests__/env-config.test.ts +0 -2
- package/scripts/utils/__tests__/multi-repo-validator.test.ts +335 -0
- package/scripts/utils/__tests__/project-meta.test.ts +192 -0
- package/scripts/utils/__tests__/security-validator.test.ts +272 -0
- package/scripts/utils/config-loader.ts +429 -56
- package/scripts/utils/env-config.ts +2 -14
- package/scripts/utils/multi-repo-validator.ts +141 -0
- package/scripts/utils/project-meta.ts +27 -0
- package/scripts/utils/security-validator.ts +286 -0
- package/scripts/utils/spec-archiver.ts +260 -0
- package/scripts/utils/spec-updater.ts +4 -0
- package/templates/claude/agents/pr-size-monitor/AGENT.md +330 -0
- package/templates/claude/commands/kiro/kiro-spec-impl.md +1 -1
- package/templates/claude/commands/michi/spec-impl.md +208 -35
- package/templates/claude-agent/commands/kiro/kiro-spec-impl.md +1 -1
- package/templates/cursor/commands/kiro/kiro-spec-impl.md +1 -1
- package/templates/multi-repo/docs/ci-status.md +51 -0
- package/templates/multi-repo/docs/release-notes.md +99 -0
- package/templates/multi-repo/overview/architecture.md +102 -0
- package/templates/multi-repo/overview/requirements.md +68 -0
- package/templates/multi-repo/overview/sequence.md +79 -0
- package/templates/multi-repo/steering/multi-repo.md +74 -0
- package/templates/multi-repo/tests/strategy.md +89 -0
- package/dist/scripts/__tests__/create-project.test.d.ts +0 -2
- package/dist/scripts/__tests__/create-project.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/create-project.test.js +0 -243
- package/dist/scripts/__tests__/create-project.test.js.map +0 -1
- package/dist/scripts/__tests__/jira-transitions.test.d.ts +0 -5
- package/dist/scripts/__tests__/jira-transitions.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/jira-transitions.test.js +0 -172
- package/dist/scripts/__tests__/jira-transitions.test.js.map +0 -1
- package/dist/scripts/__tests__/multi-project-estimate.test.d.ts +0 -2
- package/dist/scripts/__tests__/multi-project-estimate.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/multi-project-estimate.test.js +0 -118
- package/dist/scripts/__tests__/multi-project-estimate.test.js.map +0 -1
- package/dist/scripts/__tests__/setup-existing-project.test.d.ts +0 -2
- package/dist/scripts/__tests__/setup-existing-project.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/setup-existing-project.test.js +0 -208
- package/dist/scripts/__tests__/setup-existing-project.test.js.map +0 -1
- package/dist/scripts/__tests__/setup-interactive.test.d.ts +0 -2
- package/dist/scripts/__tests__/setup-interactive.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/setup-interactive.test.js +0 -166
- package/dist/scripts/__tests__/setup-interactive.test.js.map +0 -1
- package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts +0 -5
- package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/spec-impl-workflow.test.js +0 -321
- package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +0 -1
- package/dist/scripts/__tests__/spec-loader.test.d.ts +0 -5
- package/dist/scripts/__tests__/spec-loader.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/spec-loader.test.js +0 -153
- package/dist/scripts/__tests__/spec-loader.test.js.map +0 -1
- package/dist/scripts/__tests__/validate-phase.test.d.ts +0 -5
- package/dist/scripts/__tests__/validate-phase.test.d.ts.map +0 -1
- package/dist/scripts/__tests__/validate-phase.test.js +0 -249
- package/dist/scripts/__tests__/validate-phase.test.js.map +0 -1
- package/dist/scripts/constants/__tests__/environments.test.d.ts +0 -2
- package/dist/scripts/constants/__tests__/environments.test.d.ts.map +0 -1
- package/dist/scripts/constants/__tests__/environments.test.js +0 -125
- package/dist/scripts/constants/__tests__/environments.test.js.map +0 -1
- package/dist/scripts/constants/__tests__/languages.test.d.ts +0 -2
- package/dist/scripts/constants/__tests__/languages.test.d.ts.map +0 -1
- package/dist/scripts/constants/__tests__/languages.test.js +0 -82
- package/dist/scripts/constants/__tests__/languages.test.js.map +0 -1
- package/dist/scripts/create-project.d.ts +0 -16
- package/dist/scripts/create-project.d.ts.map +0 -1
- package/dist/scripts/create-project.js +0 -334
- package/dist/scripts/create-project.js.map +0 -1
- package/dist/scripts/list-projects.d.ts +0 -7
- package/dist/scripts/list-projects.d.ts.map +0 -1
- package/dist/scripts/list-projects.js +0 -88
- package/dist/scripts/list-projects.js.map +0 -1
- package/dist/scripts/template/__tests__/renderer.test.d.ts +0 -2
- package/dist/scripts/template/__tests__/renderer.test.d.ts.map +0 -1
- package/dist/scripts/template/__tests__/renderer.test.js +0 -165
- package/dist/scripts/template/__tests__/renderer.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/aidlc-parser.test.js +0 -315
- package/dist/scripts/utils/__tests__/aidlc-parser.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/business-days.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/business-days.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/business-days.test.js +0 -171
- package/dist/scripts/utils/__tests__/business-days.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/config-loader.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/config-loader.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/config-loader.test.js +0 -201
- package/dist/scripts/utils/__tests__/config-loader.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/config-validator.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/config-validator.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/config-validator.test.js +0 -394
- package/dist/scripts/utils/__tests__/config-validator.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/env-config.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/env-config.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/env-config.test.js +0 -218
- package/dist/scripts/utils/__tests__/env-config.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/feature-name-validator.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/feature-name-validator.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/feature-name-validator.test.js +0 -106
- package/dist/scripts/utils/__tests__/feature-name-validator.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js +0 -202
- package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/spec-updater.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/spec-updater.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/spec-updater.test.js +0 -158
- package/dist/scripts/utils/__tests__/spec-updater.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/tasks-converter.test.js +0 -500
- package/dist/scripts/utils/__tests__/tasks-converter.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.js +0 -314
- package/dist/scripts/utils/__tests__/tasks-format-validator.test.js.map +0 -1
- package/dist/scripts/utils/__tests__/test-runner.test.d.ts +0 -5
- package/dist/scripts/utils/__tests__/test-runner.test.d.ts.map +0 -1
- package/dist/scripts/utils/__tests__/test-runner.test.js +0 -64
- package/dist/scripts/utils/__tests__/test-runner.test.js.map +0 -1
- package/dist/src/__tests__/cli.test.d.ts +0 -5
- package/dist/src/__tests__/cli.test.d.ts.map +0 -1
- package/dist/src/__tests__/cli.test.js +0 -58
- package/dist/src/__tests__/cli.test.js.map +0 -1
- package/dist/src/__tests__/integration/internationalization.test.d.ts +0 -8
- package/dist/src/__tests__/integration/internationalization.test.d.ts.map +0 -1
- package/dist/src/__tests__/integration/internationalization.test.js +0 -333
- package/dist/src/__tests__/integration/internationalization.test.js.map +0 -1
- package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +0 -5
- package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/claude-agent.test.js +0 -122
- package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +0 -1
- package/dist/src/__tests__/integration/setup/claude.test.d.ts +0 -5
- package/dist/src/__tests__/integration/setup/claude.test.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/claude.test.js +0 -193
- package/dist/src/__tests__/integration/setup/claude.test.js.map +0 -1
- package/dist/src/__tests__/integration/setup/cursor.test.d.ts +0 -5
- package/dist/src/__tests__/integration/setup/cursor.test.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/cursor.test.js +0 -166
- package/dist/src/__tests__/integration/setup/cursor.test.js.map +0 -1
- package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts +0 -32
- package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js +0 -72
- package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js.map +0 -1
- package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts +0 -38
- package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/helpers/test-project.js +0 -83
- package/dist/src/__tests__/integration/setup/helpers/test-project.js.map +0 -1
- package/dist/src/__tests__/integration/setup/init.test.d.ts +0 -5
- package/dist/src/__tests__/integration/setup/init.test.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/init.test.js +0 -352
- package/dist/src/__tests__/integration/setup/init.test.js.map +0 -1
- package/dist/src/__tests__/integration/setup/validation.test.d.ts +0 -5
- package/dist/src/__tests__/integration/setup/validation.test.d.ts.map +0 -1
- package/dist/src/__tests__/integration/setup/validation.test.js +0 -301
- package/dist/src/__tests__/integration/setup/validation.test.js.map +0 -1
- package/scripts/create-project.ts +0 -386
- package/scripts/list-projects.ts +0 -112
|
@@ -3,12 +3,19 @@
|
|
|
3
3
|
* デフォルト設定 + プロジェクト固有設定をマージ
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { readFileSync, existsSync, statSync } from 'fs';
|
|
7
|
-
import { resolve, relative, isAbsolute } from 'path';
|
|
6
|
+
import { readFileSync, writeFileSync, existsSync, statSync, renameSync, unlinkSync, mkdirSync } from 'fs';
|
|
7
|
+
import { resolve, relative, isAbsolute, dirname } from 'path';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
import { homedir } from 'os';
|
|
10
|
-
import { config } from 'dotenv';
|
|
11
|
-
import {
|
|
10
|
+
import { config, parse as dotenvParse } from 'dotenv';
|
|
11
|
+
import {
|
|
12
|
+
AppConfigSchema,
|
|
13
|
+
MultiRepoProjectSchema,
|
|
14
|
+
RepositorySchema,
|
|
15
|
+
type AppConfig,
|
|
16
|
+
type MultiRepoProject,
|
|
17
|
+
type Repository,
|
|
18
|
+
} from '../config/config-schema.js';
|
|
12
19
|
|
|
13
20
|
// 環境変数読み込み
|
|
14
21
|
config();
|
|
@@ -27,6 +34,14 @@ export function getGlobalConfigPath(): string {
|
|
|
27
34
|
return resolve(home, GLOBAL_CONFIG_DIR, GLOBAL_CONFIG_FILE);
|
|
28
35
|
}
|
|
29
36
|
|
|
37
|
+
/**
|
|
38
|
+
* グローバル.envファイルのパスを取得
|
|
39
|
+
*/
|
|
40
|
+
export function getGlobalEnvPath(): string {
|
|
41
|
+
const home = process.env.HOME || homedir();
|
|
42
|
+
return resolve(home, GLOBAL_CONFIG_DIR, '.env');
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
/**
|
|
31
46
|
* 深いマージ(Deep Merge)
|
|
32
47
|
* オブジェクトを再帰的にマージする
|
|
@@ -244,73 +259,172 @@ function loadGlobalConfig(): Partial<AppConfig> | null {
|
|
|
244
259
|
}
|
|
245
260
|
}
|
|
246
261
|
|
|
262
|
+
/**
|
|
263
|
+
* グローバル.envを読み込み
|
|
264
|
+
* ~/.michi/.env から組織共通の環境変数を読み込む
|
|
265
|
+
*/
|
|
266
|
+
function loadGlobalEnv(): Record<string, string> {
|
|
267
|
+
const globalEnvPath = getGlobalEnvPath();
|
|
268
|
+
|
|
269
|
+
if (!existsSync(globalEnvPath)) {
|
|
270
|
+
return {};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
const content = readFileSync(globalEnvPath, 'utf-8');
|
|
275
|
+
return dotenvParse(content);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.warn(`⚠️ Failed to load global env from ${globalEnvPath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
278
|
+
return {};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* プロジェクト.envを読み込み
|
|
284
|
+
* .env からプロジェクト固有の環境変数を読み込む
|
|
285
|
+
*/
|
|
286
|
+
function loadProjectEnv(projectRoot: string): Record<string, string> {
|
|
287
|
+
const projectEnvPath = resolve(projectRoot, '.env');
|
|
288
|
+
|
|
289
|
+
if (!existsSync(projectEnvPath)) {
|
|
290
|
+
return {};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
const content = readFileSync(projectEnvPath, 'utf-8');
|
|
295
|
+
return dotenvParse(content);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
console.warn(`⚠️ Failed to load project env from ${projectEnvPath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
298
|
+
return {};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* プロジェクトメタデータを読み込み
|
|
304
|
+
* .kiro/project.json からプロジェクト情報を読み込む
|
|
305
|
+
*/
|
|
306
|
+
function loadProjectMetadata(projectRoot: string): Partial<AppConfig> | null {
|
|
307
|
+
const projectJsonPath = resolve(projectRoot, '.kiro/project.json');
|
|
308
|
+
|
|
309
|
+
if (!existsSync(projectJsonPath)) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
const content = readFileSync(projectJsonPath, 'utf-8');
|
|
315
|
+
const meta = JSON.parse(content);
|
|
316
|
+
|
|
317
|
+
// project フィールドとして返す
|
|
318
|
+
return { project: meta } as Partial<AppConfig>;
|
|
319
|
+
} catch (error) {
|
|
320
|
+
if (error instanceof SyntaxError) {
|
|
321
|
+
console.warn(`⚠️ Invalid JSON in ${projectJsonPath}: ${error.message}`);
|
|
322
|
+
} else {
|
|
323
|
+
console.warn(`⚠️ Failed to load project metadata from ${projectJsonPath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
324
|
+
}
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* 環境変数から設定へのマッピング
|
|
331
|
+
*/
|
|
332
|
+
const ENV_TO_CONFIG_MAPPING: Record<string, string> = {
|
|
333
|
+
'ATLASSIAN_URL': 'atlassian.url',
|
|
334
|
+
'ATLASSIAN_EMAIL': 'atlassian.email',
|
|
335
|
+
'ATLASSIAN_API_TOKEN': 'atlassian.apiToken',
|
|
336
|
+
'GITHUB_ORG': 'github.org',
|
|
337
|
+
'GITHUB_TOKEN': 'github.token',
|
|
338
|
+
'CONFLUENCE_PRD_SPACE': 'confluence.spaces.requirements',
|
|
339
|
+
'CONFLUENCE_QA_SPACE': 'confluence.spaces.qa',
|
|
340
|
+
'CONFLUENCE_RELEASE_SPACE': 'confluence.spaces.release',
|
|
341
|
+
'JIRA_ISSUE_TYPE_STORY': 'jira.issueTypes.story',
|
|
342
|
+
'JIRA_ISSUE_TYPE_SUBTASK': 'jira.issueTypes.subtask',
|
|
343
|
+
'JIRA_PROJECT_KEYS': 'jira.projectKeys',
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* ドットパスでオブジェクトの値を設定
|
|
348
|
+
* 例: setValueByPath(obj, 'a.b.c', value) => obj.a.b.c = value
|
|
349
|
+
*/
|
|
350
|
+
function setValueByPath(obj: Record<string, unknown>, path: string, value: string): void {
|
|
351
|
+
const keys = path.split('.');
|
|
352
|
+
let current: Record<string, unknown> = obj;
|
|
353
|
+
|
|
354
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
355
|
+
const key = keys[i];
|
|
356
|
+
if (!current[key] || typeof current[key] !== 'object') {
|
|
357
|
+
current[key] = {};
|
|
358
|
+
}
|
|
359
|
+
current = current[key] as Record<string, unknown>;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
current[keys[keys.length - 1]] = value;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* 環境変数を設定オブジェクトに適用
|
|
367
|
+
*/
|
|
368
|
+
function applyEnvVarsToConfig(
|
|
369
|
+
config: AppConfig,
|
|
370
|
+
envVars: Record<string, string>
|
|
371
|
+
): AppConfig {
|
|
372
|
+
const result = { ...config } as Record<string, unknown>;
|
|
373
|
+
|
|
374
|
+
for (const [envKey, configPath] of Object.entries(ENV_TO_CONFIG_MAPPING)) {
|
|
375
|
+
if (envVars[envKey]) {
|
|
376
|
+
setValueByPath(result, configPath, envVars[envKey]);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return result as AppConfig;
|
|
381
|
+
}
|
|
382
|
+
|
|
247
383
|
/**
|
|
248
384
|
* 設定を読み込んでマージ
|
|
249
385
|
*
|
|
250
|
-
*
|
|
386
|
+
* マージ順序(優先度: 低 → 高):
|
|
251
387
|
* 1. デフォルト設定
|
|
252
|
-
* 2.
|
|
253
|
-
* 3.
|
|
254
|
-
* 4.
|
|
388
|
+
* 2. グローバル.env(~/.michi/.env)
|
|
389
|
+
* 3. グローバル設定(~/.michi/config.json)
|
|
390
|
+
* 4. プロジェクトメタデータ(.kiro/project.json)
|
|
391
|
+
* 5. プロジェクト設定(.michi/config.json)
|
|
392
|
+
* 6. プロジェクト.env(.env)- 最高優先度
|
|
255
393
|
*/
|
|
256
394
|
export function loadConfig(projectRoot: string = process.cwd()): AppConfig {
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
// グローバル設定を読み込み
|
|
261
|
-
const globalConfig = loadGlobalConfig();
|
|
395
|
+
// 1. デフォルト設定を読み込み(最低優先度)
|
|
396
|
+
let mergedConfig: AppConfig = loadDefaultConfig();
|
|
262
397
|
|
|
263
|
-
//
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
398
|
+
// 2. グローバル.envを読み込み
|
|
399
|
+
const globalEnvVars = loadGlobalEnv();
|
|
400
|
+
if (Object.keys(globalEnvVars).length > 0) {
|
|
401
|
+
mergedConfig = applyEnvVarsToConfig(mergedConfig, globalEnvVars);
|
|
402
|
+
}
|
|
268
403
|
|
|
404
|
+
// 3. グローバル設定を読み込み
|
|
405
|
+
const globalConfig = loadGlobalConfig();
|
|
269
406
|
if (globalConfig) {
|
|
270
407
|
mergedConfig = deepMerge(mergedConfig, globalConfig);
|
|
271
408
|
}
|
|
272
409
|
|
|
410
|
+
// 4. プロジェクトメタデータを読み込み
|
|
411
|
+
const projectMeta = loadProjectMetadata(projectRoot);
|
|
412
|
+
if (projectMeta) {
|
|
413
|
+
mergedConfig = deepMerge(mergedConfig, projectMeta);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// 5. プロジェクト固有設定を読み込み
|
|
417
|
+
const projectConfig = loadProjectConfig(projectRoot);
|
|
273
418
|
if (projectConfig) {
|
|
274
419
|
mergedConfig = deepMerge(mergedConfig, projectConfig);
|
|
275
420
|
}
|
|
276
|
-
|
|
277
|
-
//
|
|
278
|
-
|
|
279
|
-
if (
|
|
280
|
-
|
|
281
|
-
mergedConfig.confluence = {
|
|
282
|
-
pageCreationGranularity: 'single',
|
|
283
|
-
pageTitleFormat: '[{projectName}] {featureName} {docTypeLabel}',
|
|
284
|
-
autoLabels: ['{projectLabel}', '{docType}', '{featureName}', 'github-sync']
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
// spacesオブジェクトを確実に作成
|
|
288
|
-
if (!mergedConfig.confluence.spaces) {
|
|
289
|
-
mergedConfig.confluence.spaces = {};
|
|
290
|
-
}
|
|
291
|
-
// 各フィールドを個別にチェックし、未定義のフィールドのみ環境変数で設定
|
|
292
|
-
// 既に定義されている値は変更しない
|
|
293
|
-
if (!mergedConfig.confluence.spaces.requirements) {
|
|
294
|
-
mergedConfig.confluence.spaces.requirements = process.env.CONFLUENCE_PRD_SPACE;
|
|
295
|
-
}
|
|
296
|
-
if (!mergedConfig.confluence.spaces.design) {
|
|
297
|
-
mergedConfig.confluence.spaces.design = process.env.CONFLUENCE_PRD_SPACE;
|
|
298
|
-
}
|
|
299
|
-
if (!mergedConfig.confluence.spaces.tasks) {
|
|
300
|
-
mergedConfig.confluence.spaces.tasks = process.env.CONFLUENCE_PRD_SPACE;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// JIRA issue type IDを環境変数から取得(インスタンス固有の値のため)
|
|
305
|
-
if (mergedConfig.jira && mergedConfig.jira.issueTypes) {
|
|
306
|
-
if (process.env.JIRA_ISSUE_TYPE_STORY) {
|
|
307
|
-
mergedConfig.jira.issueTypes.story = process.env.JIRA_ISSUE_TYPE_STORY;
|
|
308
|
-
}
|
|
309
|
-
if (process.env.JIRA_ISSUE_TYPE_SUBTASK) {
|
|
310
|
-
mergedConfig.jira.issueTypes.subtask = process.env.JIRA_ISSUE_TYPE_SUBTASK;
|
|
311
|
-
}
|
|
421
|
+
|
|
422
|
+
// 6. プロジェクト.envを読み込み(最高優先度)
|
|
423
|
+
const projectEnvVars = loadProjectEnv(projectRoot);
|
|
424
|
+
if (Object.keys(projectEnvVars).length > 0) {
|
|
425
|
+
mergedConfig = applyEnvVarsToConfig(mergedConfig, projectEnvVars);
|
|
312
426
|
}
|
|
313
|
-
|
|
427
|
+
|
|
314
428
|
// スキーマで最終バリデーション
|
|
315
429
|
return AppConfigSchema.parse(mergedConfig);
|
|
316
430
|
}
|
|
@@ -324,10 +438,16 @@ let cachedProjectRoot: string | null = null;
|
|
|
324
438
|
let cachedConfigMtime: number | null = null;
|
|
325
439
|
let cachedDefaultConfigMtime: number | null = null;
|
|
326
440
|
let cachedGlobalConfigMtime: number | null = null;
|
|
441
|
+
let cachedGlobalEnvMtime: number | null = null;
|
|
442
|
+
let cachedProjectMetaMtime: number | null = null;
|
|
443
|
+
let cachedProjectEnvMtime: number | null = null;
|
|
327
444
|
|
|
328
445
|
export function getConfig(projectRoot: string = process.cwd()): AppConfig {
|
|
329
446
|
const projectConfigPath = resolveConfigPath(projectRoot);
|
|
330
447
|
const globalConfigPath = getGlobalConfigPath();
|
|
448
|
+
const globalEnvPath = getGlobalEnvPath();
|
|
449
|
+
const projectMetaPath = resolve(projectRoot, '.kiro/project.json');
|
|
450
|
+
const projectEnvPath = resolve(projectRoot, '.env');
|
|
331
451
|
const currentFileUrl = import.meta.url;
|
|
332
452
|
const currentFilePath = fileURLToPath(currentFileUrl);
|
|
333
453
|
const currentDir = resolve(currentFilePath, '..');
|
|
@@ -397,13 +517,76 @@ export function getConfig(projectRoot: string = process.cwd()): AppConfig {
|
|
|
397
517
|
cachedConfigMtime = null;
|
|
398
518
|
}
|
|
399
519
|
|
|
520
|
+
// グローバル.envファイルの更新時刻をチェック
|
|
521
|
+
let globalEnvChanged = false;
|
|
522
|
+
try {
|
|
523
|
+
if (existsSync(globalEnvPath)) {
|
|
524
|
+
const globalEnvStats = statSync(globalEnvPath);
|
|
525
|
+
if (cachedGlobalEnvMtime !== globalEnvStats.mtimeMs) {
|
|
526
|
+
globalEnvChanged = true;
|
|
527
|
+
cachedGlobalEnvMtime = globalEnvStats.mtimeMs;
|
|
528
|
+
}
|
|
529
|
+
} else {
|
|
530
|
+
if (cachedGlobalEnvMtime !== null) {
|
|
531
|
+
globalEnvChanged = true;
|
|
532
|
+
cachedGlobalEnvMtime = null;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
} catch {
|
|
536
|
+
globalEnvChanged = true;
|
|
537
|
+
cachedGlobalEnvMtime = null;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// プロジェクトメタデータファイルの更新時刻をチェック
|
|
541
|
+
let projectMetaChanged = false;
|
|
542
|
+
try {
|
|
543
|
+
if (existsSync(projectMetaPath)) {
|
|
544
|
+
const projectMetaStats = statSync(projectMetaPath);
|
|
545
|
+
if (cachedProjectMetaMtime !== projectMetaStats.mtimeMs) {
|
|
546
|
+
projectMetaChanged = true;
|
|
547
|
+
cachedProjectMetaMtime = projectMetaStats.mtimeMs;
|
|
548
|
+
}
|
|
549
|
+
} else {
|
|
550
|
+
if (cachedProjectMetaMtime !== null) {
|
|
551
|
+
projectMetaChanged = true;
|
|
552
|
+
cachedProjectMetaMtime = null;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
} catch {
|
|
556
|
+
projectMetaChanged = true;
|
|
557
|
+
cachedProjectMetaMtime = null;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// プロジェクト.envファイルの更新時刻をチェック
|
|
561
|
+
let projectEnvChanged = false;
|
|
562
|
+
try {
|
|
563
|
+
if (existsSync(projectEnvPath)) {
|
|
564
|
+
const projectEnvStats = statSync(projectEnvPath);
|
|
565
|
+
if (cachedProjectEnvMtime !== projectEnvStats.mtimeMs) {
|
|
566
|
+
projectEnvChanged = true;
|
|
567
|
+
cachedProjectEnvMtime = projectEnvStats.mtimeMs;
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
if (cachedProjectEnvMtime !== null) {
|
|
571
|
+
projectEnvChanged = true;
|
|
572
|
+
cachedProjectEnvMtime = null;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
} catch {
|
|
576
|
+
projectEnvChanged = true;
|
|
577
|
+
cachedProjectEnvMtime = null;
|
|
578
|
+
}
|
|
579
|
+
|
|
400
580
|
// キャッシュが有効で、設定ファイルが変更されていない場合はキャッシュを返す
|
|
401
581
|
if (
|
|
402
582
|
cachedConfig &&
|
|
403
583
|
cachedProjectRoot === projectRoot &&
|
|
404
584
|
!defaultConfigChanged &&
|
|
405
585
|
!globalConfigChanged &&
|
|
406
|
-
!
|
|
586
|
+
!globalEnvChanged &&
|
|
587
|
+
!projectConfigChanged &&
|
|
588
|
+
!projectMetaChanged &&
|
|
589
|
+
!projectEnvChanged
|
|
407
590
|
) {
|
|
408
591
|
return cachedConfig;
|
|
409
592
|
}
|
|
@@ -424,6 +607,9 @@ export function clearConfigCache(): void {
|
|
|
424
607
|
cachedConfigMtime = null;
|
|
425
608
|
cachedDefaultConfigMtime = null;
|
|
426
609
|
cachedGlobalConfigMtime = null;
|
|
610
|
+
cachedGlobalEnvMtime = null;
|
|
611
|
+
cachedProjectMetaMtime = null;
|
|
612
|
+
cachedProjectEnvMtime = null;
|
|
427
613
|
}
|
|
428
614
|
|
|
429
615
|
/**
|
|
@@ -433,3 +619,190 @@ export function getConfigPath(projectRoot: string = process.cwd()): string {
|
|
|
433
619
|
return resolveConfigPath(projectRoot);
|
|
434
620
|
}
|
|
435
621
|
|
|
622
|
+
/**
|
|
623
|
+
* Multi-Repo管理関数
|
|
624
|
+
*/
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* 設定ファイルをアトミックに保存
|
|
628
|
+
* 一時ファイルに書き込んでからrenameすることでアトミック性を保証
|
|
629
|
+
*/
|
|
630
|
+
function saveConfig(
|
|
631
|
+
config: Partial<AppConfig>,
|
|
632
|
+
projectRoot: string = process.cwd(),
|
|
633
|
+
): void {
|
|
634
|
+
const configPath = resolveConfigPath(projectRoot);
|
|
635
|
+
const tempPath = `${configPath}.tmp`;
|
|
636
|
+
|
|
637
|
+
try {
|
|
638
|
+
// .michiディレクトリが存在しない場合は作成
|
|
639
|
+
const configDir = dirname(configPath);
|
|
640
|
+
if (!existsSync(configDir)) {
|
|
641
|
+
mkdirSync(configDir, { recursive: true });
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// 一時ファイルに書き込み
|
|
645
|
+
writeFileSync(tempPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
646
|
+
|
|
647
|
+
// アトミックにリネーム
|
|
648
|
+
renameSync(tempPath, configPath);
|
|
649
|
+
|
|
650
|
+
// キャッシュをクリア
|
|
651
|
+
clearConfigCache();
|
|
652
|
+
} catch (error) {
|
|
653
|
+
// エラー時は一時ファイルを削除
|
|
654
|
+
if (existsSync(tempPath)) {
|
|
655
|
+
try {
|
|
656
|
+
unlinkSync(tempPath);
|
|
657
|
+
} catch {
|
|
658
|
+
// 削除失敗は無視
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
throw error;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* プロジェクト名でMulti-Repoプロジェクトを検索
|
|
667
|
+
*/
|
|
668
|
+
export function findProject(
|
|
669
|
+
projectName: string,
|
|
670
|
+
projectRoot: string = process.cwd(),
|
|
671
|
+
): MultiRepoProject | null {
|
|
672
|
+
const configPath = resolveConfigPath(projectRoot);
|
|
673
|
+
|
|
674
|
+
if (!existsSync(configPath)) {
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
try {
|
|
679
|
+
const config = loadProjectConfig(projectRoot);
|
|
680
|
+
if (!config?.multiRepoProjects) {
|
|
681
|
+
return null;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const project = config.multiRepoProjects.find(
|
|
685
|
+
(p) => p.name === projectName,
|
|
686
|
+
);
|
|
687
|
+
return project || null;
|
|
688
|
+
} catch {
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Multi-Repoプロジェクトを追加
|
|
695
|
+
*/
|
|
696
|
+
export function addMultiRepoProject(
|
|
697
|
+
project: MultiRepoProject,
|
|
698
|
+
projectRoot: string = process.cwd(),
|
|
699
|
+
): { success: boolean; project?: MultiRepoProject; error?: string } {
|
|
700
|
+
try {
|
|
701
|
+
// Zodスキーマでバリデーション
|
|
702
|
+
const validatedProject = MultiRepoProjectSchema.parse(project);
|
|
703
|
+
|
|
704
|
+
// 既存の設定を読み込み
|
|
705
|
+
const existingConfig = loadProjectConfig(projectRoot) || {};
|
|
706
|
+
const multiRepoProjects = existingConfig.multiRepoProjects || [];
|
|
707
|
+
|
|
708
|
+
// 重複チェック
|
|
709
|
+
const existingProject = multiRepoProjects.find(
|
|
710
|
+
(p) => p.name === validatedProject.name,
|
|
711
|
+
);
|
|
712
|
+
if (existingProject) {
|
|
713
|
+
return {
|
|
714
|
+
success: false,
|
|
715
|
+
error: `Project "${validatedProject.name}" already exists`,
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// プロジェクトを追加
|
|
720
|
+
const updatedConfig = {
|
|
721
|
+
...existingConfig,
|
|
722
|
+
multiRepoProjects: [...multiRepoProjects, validatedProject],
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// 設定を保存
|
|
726
|
+
saveConfig(updatedConfig, projectRoot);
|
|
727
|
+
|
|
728
|
+
return {
|
|
729
|
+
success: true,
|
|
730
|
+
project: validatedProject,
|
|
731
|
+
};
|
|
732
|
+
} catch (error) {
|
|
733
|
+
return {
|
|
734
|
+
success: false,
|
|
735
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Multi-Repoプロジェクトにリポジトリを追加
|
|
742
|
+
*/
|
|
743
|
+
export function addRepositoryToProject(
|
|
744
|
+
projectName: string,
|
|
745
|
+
repository: Repository,
|
|
746
|
+
projectRoot: string = process.cwd(),
|
|
747
|
+
): { success: boolean; repository?: Repository; error?: string } {
|
|
748
|
+
try {
|
|
749
|
+
// Zodスキーマでバリデーション
|
|
750
|
+
const validatedRepo = RepositorySchema.parse(repository);
|
|
751
|
+
|
|
752
|
+
// 既存の設定を読み込み
|
|
753
|
+
const existingConfig = loadProjectConfig(projectRoot) || {};
|
|
754
|
+
const multiRepoProjects = existingConfig.multiRepoProjects || [];
|
|
755
|
+
|
|
756
|
+
// プロジェクトを検索
|
|
757
|
+
const projectIndex = multiRepoProjects.findIndex(
|
|
758
|
+
(p) => p.name === projectName,
|
|
759
|
+
);
|
|
760
|
+
if (projectIndex === -1) {
|
|
761
|
+
return {
|
|
762
|
+
success: false,
|
|
763
|
+
error: `Project "${projectName}" not found`,
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
const project = multiRepoProjects[projectIndex];
|
|
768
|
+
|
|
769
|
+
// 重複チェック
|
|
770
|
+
const existingRepo = project.repositories.find(
|
|
771
|
+
(r) => r.name === validatedRepo.name,
|
|
772
|
+
);
|
|
773
|
+
if (existingRepo) {
|
|
774
|
+
return {
|
|
775
|
+
success: false,
|
|
776
|
+
error: `Repository "${validatedRepo.name}" already exists in project "${projectName}"`,
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// リポジトリを追加
|
|
781
|
+
const updatedProject = {
|
|
782
|
+
...project,
|
|
783
|
+
repositories: [...project.repositories, validatedRepo],
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
// プロジェクト配列を更新
|
|
787
|
+
const updatedProjects = [...multiRepoProjects];
|
|
788
|
+
updatedProjects[projectIndex] = updatedProject;
|
|
789
|
+
|
|
790
|
+
// 設定を保存
|
|
791
|
+
const updatedConfig = {
|
|
792
|
+
...existingConfig,
|
|
793
|
+
multiRepoProjects: updatedProjects,
|
|
794
|
+
};
|
|
795
|
+
saveConfig(updatedConfig, projectRoot);
|
|
796
|
+
|
|
797
|
+
return {
|
|
798
|
+
success: true,
|
|
799
|
+
repository: validatedRepo,
|
|
800
|
+
};
|
|
801
|
+
} catch (error) {
|
|
802
|
+
return {
|
|
803
|
+
success: false,
|
|
804
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
@@ -61,11 +61,6 @@ const ENV_CONFIG: EnvValue[] = [
|
|
|
61
61
|
required: false,
|
|
62
62
|
sensitive: true,
|
|
63
63
|
},
|
|
64
|
-
{
|
|
65
|
-
key: 'GITHUB_REPO',
|
|
66
|
-
description: 'GitHubリポジトリ (例: owner/repo)',
|
|
67
|
-
required: false,
|
|
68
|
-
},
|
|
69
64
|
{
|
|
70
65
|
key: 'CONFLUENCE_PRD_SPACE',
|
|
71
66
|
description: 'Confluence PRDスペースキー',
|
|
@@ -435,7 +430,7 @@ export function generateEnvContent(values: Map<string, string>): string {
|
|
|
435
430
|
|
|
436
431
|
// GitHub設定
|
|
437
432
|
content += '\n# GitHub設定\n';
|
|
438
|
-
const githubKeys = ['GITHUB_ORG', 'GITHUB_TOKEN'
|
|
433
|
+
const githubKeys = ['GITHUB_ORG', 'GITHUB_TOKEN'];
|
|
439
434
|
for (const key of githubKeys) {
|
|
440
435
|
const value = values.get(key) || '';
|
|
441
436
|
content += `${key}=${value}\n`;
|
|
@@ -477,7 +472,7 @@ export function generateEnvContent(values: Map<string, string>): string {
|
|
|
477
472
|
export async function configureEnvInteractive(
|
|
478
473
|
existingValues?: Map<string, string>,
|
|
479
474
|
jiraKey?: string,
|
|
480
|
-
|
|
475
|
+
_repoUrl?: string,
|
|
481
476
|
): Promise<Map<string, string>> {
|
|
482
477
|
const rl = readline.createInterface({
|
|
483
478
|
input: process.stdin,
|
|
@@ -500,13 +495,6 @@ export async function configureEnvInteractive(
|
|
|
500
495
|
if (config.key === 'JIRA_PROJECT_KEYS' && jiraKey && !existingValue) {
|
|
501
496
|
existingValue = jiraKey;
|
|
502
497
|
}
|
|
503
|
-
if (config.key === 'GITHUB_REPO' && repoUrl && !existingValue) {
|
|
504
|
-
// URLからリポジトリ名を抽出 (例: https://github.com/owner/repo -> owner/repo)
|
|
505
|
-
const match = repoUrl.match(/github\.com[/:]([\w-]+\/[\w-]+)/);
|
|
506
|
-
if (match) {
|
|
507
|
-
existingValue = match[1];
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
498
|
|
|
511
499
|
// JIRA Issue Type ID設定時は、プロジェクトキーを渡す
|
|
512
500
|
const projectKey = jiraKey || existingValues?.get('JIRA_PROJECT_KEYS');
|