vibe-commander 0.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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/cli/commands/context-resolver.d.ts +29 -0
  3. package/dist/adapters/cli/commands/context-resolver.js +93 -0
  4. package/dist/adapters/cli/commands/context.d.ts +26 -0
  5. package/dist/adapters/cli/commands/context.js +39 -0
  6. package/dist/adapters/cli/commands/git-helpers.d.ts +43 -0
  7. package/dist/adapters/cli/commands/git-helpers.js +99 -0
  8. package/dist/adapters/cli/commands/init-helpers.d.ts +30 -0
  9. package/dist/adapters/cli/commands/init-helpers.js +112 -0
  10. package/dist/adapters/cli/commands/init-interactive.d.ts +25 -0
  11. package/dist/adapters/cli/commands/init-interactive.js +143 -0
  12. package/dist/adapters/cli/commands/init.d.ts +25 -0
  13. package/dist/adapters/cli/commands/init.js +73 -0
  14. package/dist/adapters/cli/commands/io-helpers.d.ts +45 -0
  15. package/dist/adapters/cli/commands/io-helpers.js +144 -0
  16. package/dist/adapters/cli/commands/list-units.d.ts +39 -0
  17. package/dist/adapters/cli/commands/list-units.js +92 -0
  18. package/dist/adapters/cli/commands/prompt-helpers.d.ts +36 -0
  19. package/dist/adapters/cli/commands/prompt-helpers.js +113 -0
  20. package/dist/adapters/cli/commands/set-unit.d.ts +44 -0
  21. package/dist/adapters/cli/commands/set-unit.js +90 -0
  22. package/dist/adapters/cli/commands/skill-install.d.ts +31 -0
  23. package/dist/adapters/cli/commands/skill-install.js +85 -0
  24. package/dist/adapters/cli/commands/state-helpers.d.ts +28 -0
  25. package/dist/adapters/cli/commands/state-helpers.js +55 -0
  26. package/dist/adapters/cli/commands/update-commit.d.ts +42 -0
  27. package/dist/adapters/cli/commands/update-commit.js +180 -0
  28. package/dist/adapters/cli/commands/validate.d.ts +40 -0
  29. package/dist/adapters/cli/commands/validate.js +219 -0
  30. package/dist/adapters/cli/formatters-list.d.ts +36 -0
  31. package/dist/adapters/cli/formatters-list.js +106 -0
  32. package/dist/adapters/cli/formatters-unit.d.ts +44 -0
  33. package/dist/adapters/cli/formatters-unit.js +287 -0
  34. package/dist/adapters/cli/formatters.d.ts +2 -0
  35. package/dist/adapters/cli/formatters.js +3 -0
  36. package/dist/adapters/cli/index.d.ts +17 -0
  37. package/dist/adapters/cli/index.js +60 -0
  38. package/dist/adapters/cli/output.d.ts +58 -0
  39. package/dist/adapters/cli/output.js +159 -0
  40. package/dist/adapters/cli/router.d.ts +99 -0
  41. package/dist/adapters/cli/router.js +419 -0
  42. package/dist/adapters/cli/scanner.d.ts +19 -0
  43. package/dist/adapters/cli/scanner.js +227 -0
  44. package/dist/adapters/pipe/stdin-reader.d.ts +23 -0
  45. package/dist/adapters/pipe/stdin-reader.js +56 -0
  46. package/dist/config/loader.d.ts +27 -0
  47. package/dist/config/loader.js +84 -0
  48. package/dist/config/resolver.d.ts +71 -0
  49. package/dist/config/resolver.js +124 -0
  50. package/dist/config/schema.d.ts +205 -0
  51. package/dist/config/schema.js +186 -0
  52. package/dist/core/parsers/backlog-parser.d.ts +25 -0
  53. package/dist/core/parsers/backlog-parser.js +255 -0
  54. package/dist/core/parsers/dep-line-parser.d.ts +36 -0
  55. package/dist/core/parsers/dep-line-parser.js +176 -0
  56. package/dist/core/parsers/dependency-extractor.d.ts +64 -0
  57. package/dist/core/parsers/dependency-extractor.js +193 -0
  58. package/dist/core/parsers/index.d.ts +20 -0
  59. package/dist/core/parsers/index.js +20 -0
  60. package/dist/core/parsers/md-utils.d.ts +81 -0
  61. package/dist/core/parsers/md-utils.js +144 -0
  62. package/dist/core/parsers/metadata-parser.d.ts +49 -0
  63. package/dist/core/parsers/metadata-parser.js +133 -0
  64. package/dist/core/parsers/pairing-question-extractor.d.ts +42 -0
  65. package/dist/core/parsers/pairing-question-extractor.js +146 -0
  66. package/dist/core/parsers/plan-parser-helpers.d.ts +61 -0
  67. package/dist/core/parsers/plan-parser-helpers.js +90 -0
  68. package/dist/core/parsers/plan-parser.d.ts +55 -0
  69. package/dist/core/parsers/plan-parser.js +69 -0
  70. package/dist/core/parsers/title-extractor.d.ts +36 -0
  71. package/dist/core/parsers/title-extractor.js +101 -0
  72. package/dist/core/renderers/index.d.ts +15 -0
  73. package/dist/core/renderers/index.js +18 -0
  74. package/dist/core/renderers/interpolate.d.ts +92 -0
  75. package/dist/core/renderers/interpolate.js +117 -0
  76. package/dist/core/renderers/marker-utils.d.ts +60 -0
  77. package/dist/core/renderers/marker-utils.js +85 -0
  78. package/dist/core/renderers/section-renderer.d.ts +31 -0
  79. package/dist/core/renderers/section-renderer.js +171 -0
  80. package/dist/core/renderers/section-updater.d.ts +72 -0
  81. package/dist/core/renderers/section-updater.js +175 -0
  82. package/dist/core/renderers/template-engine.d.ts +69 -0
  83. package/dist/core/renderers/template-engine.js +92 -0
  84. package/dist/core/renderers/updater-helpers.d.ts +45 -0
  85. package/dist/core/renderers/updater-helpers.js +83 -0
  86. package/dist/core/resolvers/commit-filter.d.ts +84 -0
  87. package/dist/core/resolvers/commit-filter.js +95 -0
  88. package/dist/core/resolvers/config-generator.d.ts +32 -0
  89. package/dist/core/resolvers/config-generator.js +112 -0
  90. package/dist/core/resolvers/config-merger.d.ts +26 -0
  91. package/dist/core/resolvers/config-merger.js +89 -0
  92. package/dist/core/resolvers/config-validator.d.ts +42 -0
  93. package/dist/core/resolvers/config-validator.js +61 -0
  94. package/dist/core/resolvers/dep-commit-resolver.d.ts +63 -0
  95. package/dist/core/resolvers/dep-commit-resolver.js +158 -0
  96. package/dist/core/resolvers/dep-doc-resolver.d.ts +70 -0
  97. package/dist/core/resolvers/dep-doc-resolver.js +84 -0
  98. package/dist/core/resolvers/index.d.ts +15 -0
  99. package/dist/core/resolvers/index.js +12 -0
  100. package/dist/index.d.ts +8 -0
  101. package/dist/index.js +8 -0
  102. package/dist/types/config.d.ts +10 -0
  103. package/dist/types/config.js +10 -0
  104. package/dist/types/context.d.ts +55 -0
  105. package/dist/types/context.js +10 -0
  106. package/dist/types/index.d.ts +15 -0
  107. package/dist/types/index.js +10 -0
  108. package/dist/types/init.d.ts +56 -0
  109. package/dist/types/init.js +10 -0
  110. package/dist/types/tool-result.d.ts +75 -0
  111. package/dist/types/tool-result.js +40 -0
  112. package/dist/types/unit.d.ts +118 -0
  113. package/dist/types/unit.js +10 -0
  114. package/package.json +71 -0
  115. package/skills/claude/SKILL.md +375 -0
  116. package/skills/common/cli-reference.md +251 -0
  117. package/skills/cursor/SKILL.md +353 -0
@@ -0,0 +1,56 @@
1
+ /**
2
+ * stdin JSON 리더 — Layer 3 (Adapter)
3
+ *
4
+ * stdin에서 전체 입력을 버퍼링하고 JSON으로 파싱한다.
5
+ * 에이전트/오케스트레이터의 파이프 연동을 위한 입력 어댑터.
6
+ *
7
+ * @module
8
+ */
9
+ import { ok, fail } from '../../types/index.js';
10
+ /**
11
+ * stdin에서 전체 데이터를 읽는다
12
+ *
13
+ * stdin stream을 EOF까지 버퍼링하여 문자열로 반환.
14
+ * TTY(터미널 직접 실행)인 경우 빈 문자열 반환.
15
+ */
16
+ export function readStdin() {
17
+ return new Promise((resolve) => {
18
+ if (process.stdin.isTTY) {
19
+ resolve('');
20
+ return;
21
+ }
22
+ let data = '';
23
+ process.stdin.setEncoding('utf-8');
24
+ process.stdin.on('data', (chunk) => {
25
+ data += chunk;
26
+ });
27
+ process.stdin.on('end', () => {
28
+ resolve(data.trim());
29
+ });
30
+ process.stdin.on('error', () => {
31
+ resolve('');
32
+ });
33
+ process.stdin.resume();
34
+ });
35
+ }
36
+ /**
37
+ * stdin 문자열을 JSON 객체로 파싱한다
38
+ *
39
+ * 빈 입력, 비-객체, 파싱 오류를 구조화된 ToolResult로 반환.
40
+ */
41
+ export function parseStdinJson(raw) {
42
+ if (!raw) {
43
+ return fail('STDIN_EMPTY', 'stdin에서 입력을 읽을 수 없습니다', '--stdin 사용 시 JSON 데이터를 파이프로 전달하세요: echo \'{"unitId":"U-001"}\' | vc set-unit --stdin');
44
+ }
45
+ try {
46
+ const parsed = JSON.parse(raw);
47
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
48
+ return fail('STDIN_INVALID_FORMAT', 'stdin 입력이 JSON 객체가 아닙니다', '예시: {"unitId": "U-001[Mvp]"}');
49
+ }
50
+ return ok(parsed);
51
+ }
52
+ catch {
53
+ return fail('STDIN_PARSE_ERROR', 'stdin JSON 파싱 실패', `입력: ${raw.substring(0, 100)}${raw.length > 100 ? '...' : ''}`);
54
+ }
55
+ }
56
+ //# sourceMappingURL=stdin-reader.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 설정 파일 로더 — vibe-commander.config.json
3
+ *
4
+ * 프로젝트 루트에서 설정 파일을 읽고, JSON 파싱 후 Zod 스키마로 검증.
5
+ * Layer 2(Resolver)에 위치하므로 파일 시스템 I/O 허용.
6
+ *
7
+ * 환경변수 오버라이드:
8
+ * - VC_CONFIG_PATH → 설정 파일 경로 자체를 변경
9
+ * - VC_COMMANDS_FILE → paths.commands 오버라이드
10
+ * - VC_ROADMAP_FILE → paths.roadmap 오버라이드
11
+ *
12
+ * @module
13
+ */
14
+ import type { ProjectConfig, ToolResult } from '../types/index.js';
15
+ /**
16
+ * 프로젝트 설정 파일을 로드하고 검증한다
17
+ *
18
+ * 1. 파일 읽기 (프로젝트 루트 + CONFIG_FILENAME)
19
+ * 2. JSON 파싱
20
+ * 3. Zod 스키마 검증 (기본값 자동 적용)
21
+ * 4. 환경변수 오버라이드 적용
22
+ *
23
+ * @param projectRoot - 프로젝트 루트 디렉토리 경로
24
+ * @returns 검증된 설정 또는 에러
25
+ */
26
+ export declare function loadConfig(projectRoot: string): ToolResult<ProjectConfig>;
27
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1,84 @@
1
+ /**
2
+ * 설정 파일 로더 — vibe-commander.config.json
3
+ *
4
+ * 프로젝트 루트에서 설정 파일을 읽고, JSON 파싱 후 Zod 스키마로 검증.
5
+ * Layer 2(Resolver)에 위치하므로 파일 시스템 I/O 허용.
6
+ *
7
+ * 환경변수 오버라이드:
8
+ * - VC_CONFIG_PATH → 설정 파일 경로 자체를 변경
9
+ * - VC_COMMANDS_FILE → paths.commands 오버라이드
10
+ * - VC_ROADMAP_FILE → paths.roadmap 오버라이드
11
+ *
12
+ * @module
13
+ */
14
+ import { readFileSync } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { ok, fail } from '../types/index.js';
17
+ import { projectConfigSchema, CONFIG_FILENAME } from './schema.js';
18
+ /**
19
+ * 프로젝트 설정 파일을 로드하고 검증한다
20
+ *
21
+ * 1. 파일 읽기 (프로젝트 루트 + CONFIG_FILENAME)
22
+ * 2. JSON 파싱
23
+ * 3. Zod 스키마 검증 (기본값 자동 적용)
24
+ * 4. 환경변수 오버라이드 적용
25
+ *
26
+ * @param projectRoot - 프로젝트 루트 디렉토리 경로
27
+ * @returns 검증된 설정 또는 에러
28
+ */
29
+ export function loadConfig(projectRoot) {
30
+ // 설정 파일 경로 결정 (VC_CONFIG_PATH 환경변수로 오버라이드 가능)
31
+ const configPath = process.env['VC_CONFIG_PATH'] ?? join(projectRoot, CONFIG_FILENAME);
32
+ // 1. 파일 읽기
33
+ let raw;
34
+ try {
35
+ raw = readFileSync(configPath, 'utf-8');
36
+ }
37
+ catch {
38
+ return fail('CONFIG_NOT_FOUND', `설정 파일을 찾을 수 없습니다: ${CONFIG_FILENAME}`, `경로: ${configPath}`);
39
+ }
40
+ // 2. JSON 파싱
41
+ let json;
42
+ try {
43
+ // UTF-8 BOM 제거
44
+ const content = raw.startsWith('\uFEFF') ? raw.slice(1) : raw;
45
+ json = JSON.parse(content);
46
+ }
47
+ catch (err) {
48
+ const detail = err instanceof Error ? err.message : String(err);
49
+ return fail('CONFIG_PARSE_ERROR', '설정 파일 JSON 파싱 실패', `경로: ${configPath}, 원인: ${detail}`);
50
+ }
51
+ // 3. Zod 스키마 검증
52
+ const result = projectConfigSchema.safeParse(json);
53
+ if (!result.success) {
54
+ const details = result.error.issues
55
+ .map((issue) => ` - ${issue.path.map(String).join('.') || '(root)'}: ${issue.message}`)
56
+ .join('\n');
57
+ return fail('CONFIG_INVALID', '설정 파일 검증 실패', details);
58
+ }
59
+ // 4. 환경변수 오버라이드 적용
60
+ const config = applyEnvOverrides(result.data);
61
+ return ok(config);
62
+ }
63
+ /**
64
+ * 환경변수 기반 설정 오버라이드 적용
65
+ *
66
+ * - VC_COMMANDS_FILE → paths.commands
67
+ * - VC_ROADMAP_FILE → paths.roadmap
68
+ */
69
+ function applyEnvOverrides(config) {
70
+ const commandsOverride = process.env['VC_COMMANDS_FILE'];
71
+ const roadmapOverride = process.env['VC_ROADMAP_FILE'];
72
+ if (commandsOverride === undefined && roadmapOverride === undefined) {
73
+ return config;
74
+ }
75
+ return {
76
+ ...config,
77
+ paths: {
78
+ ...config.paths,
79
+ ...(commandsOverride !== undefined && { commands: commandsOverride }),
80
+ ...(roadmapOverride !== undefined && { roadmap: roadmapOverride }),
81
+ },
82
+ };
83
+ }
84
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 유닛 유형/경로 해석기 — Layer 2 (Project Resolver)
3
+ *
4
+ * 유닛 ID를 입력받아 유형 판별, 계획서 위치, 문서 디렉토리를 해석.
5
+ * 프로젝트별 차이를 `ProjectConfig` 설정으로 흡수하는 핵심 계층.
6
+ *
7
+ * 의존성 방향: resolver.ts → types/ (OK), resolver.ts → core/renderers/ (Layer 2 → Layer 1, OK)
8
+ *
9
+ * @module
10
+ */
11
+ import type { ProjectConfig, UnitTypeConfig, DocLocationEntry } from '../types/index.js';
12
+ import type { ToolResult } from '../types/index.js';
13
+ export type { DocLocationEntry };
14
+ /**
15
+ * 유닛 ID에서 유형을 판별한다
16
+ *
17
+ * config.unitTypes 배열을 순서대로 순회하며 idPattern 정규식 매칭.
18
+ * 첫 번째 매칭된 유형의 전체 설정을 반환.
19
+ *
20
+ * ⚠️ unitTypes 배열 순서가 매칭 우선순위를 결정하므로,
21
+ * 구체적인 패턴(refactor-sub)을 포괄적인 패턴(refactor) 앞에 배치해야 함.
22
+ *
23
+ * @param unitId - 유닛 ID (예: "U-118[Mmp]", "RU-010-S3")
24
+ * @param config - 프로젝트 설정
25
+ * @returns 매칭된 UnitTypeConfig 또는 에러
26
+ */
27
+ export declare function resolveUnitType(unitId: string, config: ProjectConfig): ToolResult<UnitTypeConfig>;
28
+ /**
29
+ * 유닛 계획서의 상대 경로를 반환한다
30
+ *
31
+ * 1. unitId로 유형 판별 (resolveUnitType)
32
+ * 2. unitType.planDir → config.paths.docRoots 매핑으로 디렉토리 결정
33
+ * 3. config.docDiscovery[planDir].pattern 보간으로 파일명 생성
34
+ * 4. 디렉토리 + 파일명 조합하여 상대 경로 반환
35
+ *
36
+ * @param unitId - 유닛 ID
37
+ * @param config - 프로젝트 설정
38
+ * @returns 계획서 상대 경로 (프로젝트 루트 기준) 또는 에러
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * locatePlan('U-004[Mvp]', config)
43
+ * // → { success: true, data: 'vibe/unit-plans/U-004[Mvp].md' }
44
+ * ```
45
+ */
46
+ export declare function locatePlan(unitId: string, config: ProjectConfig): ToolResult<string>;
47
+ /**
48
+ * 유닛 관련 모든 역할의 문서 위치를 반환한다
49
+ *
50
+ * config.paths.docRoots의 모든 역할에 대해 디렉토리 경로와
51
+ * 보간된 파일 패턴을 생성. Adapter에서 의존 유닛 문서 탐색에 사용.
52
+ *
53
+ * docDiscovery에 해당 역할의 규칙이 없으면 기본 패턴({{unitId}}.md) 적용.
54
+ * glob 필드가 true인 역할은 와일드카드 매칭이 필요함을 표시.
55
+ *
56
+ * @param unitId - 유닛 ID (보통 의존 유닛의 ID)
57
+ * @param config - 프로젝트 설정
58
+ * @returns 역할별 문서 위치 배열 또는 에러
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * locateDocs('U-003[Mvp]', config)
63
+ * // → { success: true, data: [
64
+ * // { role: 'plan', dir: 'vibe/unit-plans', filePattern: 'U-003[Mvp].md', ... },
65
+ * // { role: 'result', dir: 'vibe/unit-results', filePattern: 'U-003[Mvp].md', ... },
66
+ * // { role: 'runbook', dir: 'vibe/unit-runbooks', filePattern: 'U-003-*-runbook.md', glob: true, ... },
67
+ * // ]}
68
+ * ```
69
+ */
70
+ export declare function locateDocs(unitId: string, config: ProjectConfig): ToolResult<DocLocationEntry[]>;
71
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1,124 @@
1
+ /**
2
+ * 유닛 유형/경로 해석기 — Layer 2 (Project Resolver)
3
+ *
4
+ * 유닛 ID를 입력받아 유형 판별, 계획서 위치, 문서 디렉토리를 해석.
5
+ * 프로젝트별 차이를 `ProjectConfig` 설정으로 흡수하는 핵심 계층.
6
+ *
7
+ * 의존성 방향: resolver.ts → types/ (OK), resolver.ts → core/renderers/ (Layer 2 → Layer 1, OK)
8
+ *
9
+ * @module
10
+ */
11
+ import { ok, fail } from '../types/index.js';
12
+ import { buildTemplateVars, interpolatePattern } from '../core/renderers/interpolate.js';
13
+ // ── 공개 API ──
14
+ /**
15
+ * 유닛 ID에서 유형을 판별한다
16
+ *
17
+ * config.unitTypes 배열을 순서대로 순회하며 idPattern 정규식 매칭.
18
+ * 첫 번째 매칭된 유형의 전체 설정을 반환.
19
+ *
20
+ * ⚠️ unitTypes 배열 순서가 매칭 우선순위를 결정하므로,
21
+ * 구체적인 패턴(refactor-sub)을 포괄적인 패턴(refactor) 앞에 배치해야 함.
22
+ *
23
+ * @param unitId - 유닛 ID (예: "U-118[Mmp]", "RU-010-S3")
24
+ * @param config - 프로젝트 설정
25
+ * @returns 매칭된 UnitTypeConfig 또는 에러
26
+ */
27
+ export function resolveUnitType(unitId, config) {
28
+ for (const unitType of config.unitTypes) {
29
+ let regex;
30
+ try {
31
+ regex = new RegExp(unitType.idPattern);
32
+ }
33
+ catch (err) {
34
+ const detail = err instanceof Error ? err.message : String(err);
35
+ return fail('INVALID_ID_PATTERN', `유효하지 않은 정규식 패턴: ${unitType.idPattern}`, `유형: ${unitType.key}, 원인: ${detail}`);
36
+ }
37
+ if (regex.test(unitId)) {
38
+ return ok(unitType);
39
+ }
40
+ }
41
+ return fail('UNIT_TYPE_NOT_FOUND', `유닛 ID에 매칭되는 유형을 찾을 수 없습니다: ${unitId}`, `등록된 유형: ${config.unitTypes.map((t) => t.key).join(', ')}`);
42
+ }
43
+ /**
44
+ * 유닛 계획서의 상대 경로를 반환한다
45
+ *
46
+ * 1. unitId로 유형 판별 (resolveUnitType)
47
+ * 2. unitType.planDir → config.paths.docRoots 매핑으로 디렉토리 결정
48
+ * 3. config.docDiscovery[planDir].pattern 보간으로 파일명 생성
49
+ * 4. 디렉토리 + 파일명 조합하여 상대 경로 반환
50
+ *
51
+ * @param unitId - 유닛 ID
52
+ * @param config - 프로젝트 설정
53
+ * @returns 계획서 상대 경로 (프로젝트 루트 기준) 또는 에러
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * locatePlan('U-004[Mvp]', config)
58
+ * // → { success: true, data: 'vibe/unit-plans/U-004[Mvp].md' }
59
+ * ```
60
+ */
61
+ export function locatePlan(unitId, config) {
62
+ // 1. 유형 판별
63
+ const typeResult = resolveUnitType(unitId, config);
64
+ if (!typeResult.success) {
65
+ return typeResult;
66
+ }
67
+ const unitType = typeResult.data;
68
+ const planDirKey = unitType.planDir;
69
+ // 2. docRoots에서 디렉토리 조회
70
+ const docRoot = config.paths.docRoots[planDirKey];
71
+ if (docRoot === undefined) {
72
+ return fail('DOC_ROOT_NOT_FOUND', `docRoots에 '${planDirKey}' 키가 존재하지 않습니다`, `등록된 키: ${Object.keys(config.paths.docRoots).join(', ')}`);
73
+ }
74
+ // 3. docDiscovery에서 파일 패턴 조회 (없으면 기본 패턴)
75
+ const discoveryRule = config.docDiscovery[planDirKey];
76
+ const pattern = discoveryRule?.pattern ?? '{{unitId}}.md';
77
+ // 4. 변수 보간 및 경로 조합
78
+ const vars = buildTemplateVars(unitId);
79
+ const fileName = interpolatePattern(pattern, vars);
80
+ return ok(`${docRoot}/${fileName}`);
81
+ }
82
+ /**
83
+ * 유닛 관련 모든 역할의 문서 위치를 반환한다
84
+ *
85
+ * config.paths.docRoots의 모든 역할에 대해 디렉토리 경로와
86
+ * 보간된 파일 패턴을 생성. Adapter에서 의존 유닛 문서 탐색에 사용.
87
+ *
88
+ * docDiscovery에 해당 역할의 규칙이 없으면 기본 패턴({{unitId}}.md) 적용.
89
+ * glob 필드가 true인 역할은 와일드카드 매칭이 필요함을 표시.
90
+ *
91
+ * @param unitId - 유닛 ID (보통 의존 유닛의 ID)
92
+ * @param config - 프로젝트 설정
93
+ * @returns 역할별 문서 위치 배열 또는 에러
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * locateDocs('U-003[Mvp]', config)
98
+ * // → { success: true, data: [
99
+ * // { role: 'plan', dir: 'vibe/unit-plans', filePattern: 'U-003[Mvp].md', ... },
100
+ * // { role: 'result', dir: 'vibe/unit-results', filePattern: 'U-003[Mvp].md', ... },
101
+ * // { role: 'runbook', dir: 'vibe/unit-runbooks', filePattern: 'U-003-*-runbook.md', glob: true, ... },
102
+ * // ]}
103
+ * ```
104
+ */
105
+ export function locateDocs(unitId, config) {
106
+ const vars = buildTemplateVars(unitId);
107
+ const entries = [];
108
+ for (const [role, dir] of Object.entries(config.paths.docRoots)) {
109
+ // docDiscovery에서 해당 역할의 규칙 조회 (없으면 기본값)
110
+ const discoveryRule = config.docDiscovery[role];
111
+ const pattern = discoveryRule?.pattern ?? '{{unitId}}.md';
112
+ const glob = discoveryRule?.glob ?? false;
113
+ const filePattern = interpolatePattern(pattern, vars);
114
+ entries.push({
115
+ role,
116
+ dir,
117
+ filePattern,
118
+ fullPattern: `${dir}/${filePattern}`,
119
+ glob,
120
+ });
121
+ }
122
+ return ok(entries);
123
+ }
124
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Zod 4 스키마 정의 — vibe-commander.config.json
3
+ *
4
+ * PRD §5 설정 파일 구조를 Zod 4 스키마로 모델링.
5
+ * 각 서브 스키마는 독립적으로 정의하여 재사용 및 테스트 용이성 확보.
6
+ * 페어링 질문 Q2(Option B) 결정에 따라 snapmit 스타일 기본값 제공.
7
+ *
8
+ * @module
9
+ */
10
+ import { z } from 'zod';
11
+ /** 기본 경로 설정 스키마 */
12
+ export declare const pathsSchema: z.ZodObject<{
13
+ commands: z.ZodDefault<z.ZodString>;
14
+ roadmap: z.ZodDefault<z.ZodNullable<z.ZodString>>;
15
+ docRoots: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
16
+ refactorSubDir: z.ZodDefault<z.ZodNullable<z.ZodString>>;
17
+ }, z.core.$strip>;
18
+ /** 유닛 유형 정의 스키마 */
19
+ export declare const unitTypeSchema: z.ZodObject<{
20
+ key: z.ZodString;
21
+ displayName: z.ZodOptional<z.ZodString>;
22
+ idPattern: z.ZodString;
23
+ planDir: z.ZodString;
24
+ commandSection: z.ZodString;
25
+ collectDeps: z.ZodBoolean;
26
+ headerTemplate: z.ZodString;
27
+ }, z.core.$strip>;
28
+ /** 개별 문서 역할의 탐색 규칙 스키마 */
29
+ export declare const docDiscoveryRuleSchema: z.ZodObject<{
30
+ pattern: z.ZodString;
31
+ glob: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
32
+ }, z.core.$strip>;
33
+ /** 문서 탐색 설정 스키마 (역할별 규칙 맵) */
34
+ export declare const docDiscoverySchema: z.ZodRecord<z.ZodString, z.ZodObject<{
35
+ pattern: z.ZodString;
36
+ glob: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
37
+ }, z.core.$strip>>;
38
+ /** 메타데이터 테이블 파싱 설정 스키마 */
39
+ export declare const metadataTableSchema: z.ZodObject<{
40
+ idField: z.ZodDefault<z.ZodString>;
41
+ phaseField: z.ZodDefault<z.ZodString>;
42
+ dependsField: z.ZodDefault<z.ZodString>;
43
+ }, z.core.$strip>;
44
+ /** 계획서 파싱 설정 스키마 */
45
+ export declare const planParsingSchema: z.ZodObject<{
46
+ titleSource: z.ZodDefault<z.ZodEnum<{
47
+ h1: "h1";
48
+ "frontmatter:title": "frontmatter:title";
49
+ }>>;
50
+ dependsSource: z.ZodDefault<z.ZodEnum<{
51
+ section: "section";
52
+ frontmatter: "frontmatter";
53
+ "metadata-table": "metadata-table";
54
+ }>>;
55
+ dependsSectionName: z.ZodDefault<z.ZodNullable<z.ZodString>>;
56
+ pairingQuestionSection: z.ZodDefault<z.ZodString>;
57
+ metadataTable: z.ZodPrefault<z.ZodObject<{
58
+ idField: z.ZodDefault<z.ZodString>;
59
+ phaseField: z.ZodDefault<z.ZodString>;
60
+ dependsField: z.ZodDefault<z.ZodString>;
61
+ }, z.core.$strip>>;
62
+ }, z.core.$strip>;
63
+ /** 상태 표시 매핑 스키마 */
64
+ export declare const statusMapSchema: z.ZodObject<{
65
+ ready: z.ZodDefault<z.ZodString>;
66
+ inProgress: z.ZodDefault<z.ZodString>;
67
+ completed: z.ZodDefault<z.ZodString>;
68
+ blocked: z.ZodDefault<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ /** 백로그(로드맵) 파싱 설정 스키마 */
71
+ export declare const backlogParsingSchema: z.ZodObject<{
72
+ sectionHeader: z.ZodDefault<z.ZodString>;
73
+ entryPattern: z.ZodDefault<z.ZodString>;
74
+ completedSection: z.ZodDefault<z.ZodString>;
75
+ statusMap: z.ZodPrefault<z.ZodObject<{
76
+ ready: z.ZodDefault<z.ZodString>;
77
+ inProgress: z.ZodDefault<z.ZodString>;
78
+ completed: z.ZodDefault<z.ZodString>;
79
+ blocked: z.ZodDefault<z.ZodString>;
80
+ }, z.core.$strip>>;
81
+ }, z.core.$strip>;
82
+ /** 커밋 탐색 설정 스키마 */
83
+ export declare const commitSearchSchema: z.ZodObject<{
84
+ strategy: z.ZodDefault<z.ZodString>;
85
+ extractId: z.ZodDefault<z.ZodString>;
86
+ maxResults: z.ZodDefault<z.ZodNumber>;
87
+ excludePaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
88
+ requirePaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
89
+ }, z.core.$strip>;
90
+ /** 커맨드 파일 섹션 설정 스키마 */
91
+ export declare const commandSectionsSchema: z.ZodObject<{
92
+ separator: z.ZodDefault<z.ZodString>;
93
+ preserveOtherSections: z.ZodDefault<z.ZodBoolean>;
94
+ commitFieldName: z.ZodDefault<z.ZodString>;
95
+ useMarkers: z.ZodDefault<z.ZodBoolean>;
96
+ }, z.core.$strip>;
97
+ /** 기본 문서 탐색 설정 */
98
+ export declare const DEFAULT_DOC_DISCOVERY: {
99
+ plan: {
100
+ pattern: string;
101
+ glob: boolean;
102
+ };
103
+ result: {
104
+ pattern: string;
105
+ glob: boolean;
106
+ };
107
+ runbook: {
108
+ pattern: string;
109
+ glob: boolean;
110
+ };
111
+ };
112
+ /** 프로젝트 설정 스키마 (vibe-commander.config.json) */
113
+ export declare const projectConfigSchema: z.ZodObject<{
114
+ $schema: z.ZodOptional<z.ZodString>;
115
+ version: z.ZodLiteral<1>;
116
+ paths: z.ZodPrefault<z.ZodObject<{
117
+ commands: z.ZodDefault<z.ZodString>;
118
+ roadmap: z.ZodDefault<z.ZodNullable<z.ZodString>>;
119
+ docRoots: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
120
+ refactorSubDir: z.ZodDefault<z.ZodNullable<z.ZodString>>;
121
+ }, z.core.$strip>>;
122
+ unitTypes: z.ZodArray<z.ZodObject<{
123
+ key: z.ZodString;
124
+ displayName: z.ZodOptional<z.ZodString>;
125
+ idPattern: z.ZodString;
126
+ planDir: z.ZodString;
127
+ commandSection: z.ZodString;
128
+ collectDeps: z.ZodBoolean;
129
+ headerTemplate: z.ZodString;
130
+ }, z.core.$strip>>;
131
+ docDiscovery: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
132
+ pattern: z.ZodString;
133
+ glob: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
134
+ }, z.core.$strip>>>;
135
+ planParsing: z.ZodPrefault<z.ZodObject<{
136
+ titleSource: z.ZodDefault<z.ZodEnum<{
137
+ h1: "h1";
138
+ "frontmatter:title": "frontmatter:title";
139
+ }>>;
140
+ dependsSource: z.ZodDefault<z.ZodEnum<{
141
+ section: "section";
142
+ frontmatter: "frontmatter";
143
+ "metadata-table": "metadata-table";
144
+ }>>;
145
+ dependsSectionName: z.ZodDefault<z.ZodNullable<z.ZodString>>;
146
+ pairingQuestionSection: z.ZodDefault<z.ZodString>;
147
+ metadataTable: z.ZodPrefault<z.ZodObject<{
148
+ idField: z.ZodDefault<z.ZodString>;
149
+ phaseField: z.ZodDefault<z.ZodString>;
150
+ dependsField: z.ZodDefault<z.ZodString>;
151
+ }, z.core.$strip>>;
152
+ }, z.core.$strip>>;
153
+ backlogParsing: z.ZodPrefault<z.ZodObject<{
154
+ sectionHeader: z.ZodDefault<z.ZodString>;
155
+ entryPattern: z.ZodDefault<z.ZodString>;
156
+ completedSection: z.ZodDefault<z.ZodString>;
157
+ statusMap: z.ZodPrefault<z.ZodObject<{
158
+ ready: z.ZodDefault<z.ZodString>;
159
+ inProgress: z.ZodDefault<z.ZodString>;
160
+ completed: z.ZodDefault<z.ZodString>;
161
+ blocked: z.ZodDefault<z.ZodString>;
162
+ }, z.core.$strip>>;
163
+ }, z.core.$strip>>;
164
+ commitSearch: z.ZodPrefault<z.ZodObject<{
165
+ strategy: z.ZodDefault<z.ZodString>;
166
+ extractId: z.ZodDefault<z.ZodString>;
167
+ maxResults: z.ZodDefault<z.ZodNumber>;
168
+ excludePaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
169
+ requirePaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
170
+ }, z.core.$strip>>;
171
+ commandSections: z.ZodPrefault<z.ZodObject<{
172
+ separator: z.ZodDefault<z.ZodString>;
173
+ preserveOtherSections: z.ZodDefault<z.ZodBoolean>;
174
+ commitFieldName: z.ZodDefault<z.ZodString>;
175
+ useMarkers: z.ZodDefault<z.ZodBoolean>;
176
+ }, z.core.$strip>>;
177
+ defaultSpecialRequests: z.ZodDefault<z.ZodArray<z.ZodString>>;
178
+ specialRequestsByType: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
179
+ customRequests: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
180
+ }, z.core.$strip>;
181
+ /** 경로 설정 추론 타입 */
182
+ export type InferredPathsConfig = z.infer<typeof pathsSchema>;
183
+ /** 유닛 유형 추론 타입 */
184
+ export type InferredUnitTypeConfig = z.infer<typeof unitTypeSchema>;
185
+ /** 문서 탐색 규칙 추론 타입 */
186
+ export type InferredDocDiscoveryRule = z.infer<typeof docDiscoveryRuleSchema>;
187
+ /** 문서 탐색 설정 추론 타입 */
188
+ export type InferredDocDiscoveryConfig = z.infer<typeof docDiscoverySchema>;
189
+ /** 메타데이터 테이블 설정 추론 타입 */
190
+ export type InferredMetadataTableConfig = z.infer<typeof metadataTableSchema>;
191
+ /** 계획서 파싱 설정 추론 타입 */
192
+ export type InferredPlanParsingConfig = z.infer<typeof planParsingSchema>;
193
+ /** 상태 매핑 추론 타입 */
194
+ export type InferredStatusMapConfig = z.infer<typeof statusMapSchema>;
195
+ /** 백로그 파싱 설정 추론 타입 */
196
+ export type InferredBacklogParsingConfig = z.infer<typeof backlogParsingSchema>;
197
+ /** 커밋 탐색 설정 추론 타입 */
198
+ export type InferredCommitSearchConfig = z.infer<typeof commitSearchSchema>;
199
+ /** 커맨드 섹션 설정 추론 타입 */
200
+ export type InferredCommandSectionsConfig = z.infer<typeof commandSectionsSchema>;
201
+ /** Zod 스키마에서 추론된 프로젝트 설정 타입 */
202
+ export type InferredProjectConfig = z.infer<typeof projectConfigSchema>;
203
+ /** 설정 파일명 */
204
+ export declare const CONFIG_FILENAME = "vibe-commander.config.json";
205
+ //# sourceMappingURL=schema.d.ts.map