@su-record/vibe 3.1.0 → 3.2.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 (123) hide show
  1. package/CLAUDE.md +2 -2
  2. package/README.en.md +6 -4
  3. package/README.md +5 -3
  4. package/dist/__tests__/wiring-integrity.test.d.ts +2 -0
  5. package/dist/__tests__/wiring-integrity.test.d.ts.map +1 -0
  6. package/dist/__tests__/wiring-integrity.test.js +160 -0
  7. package/dist/__tests__/wiring-integrity.test.js.map +1 -0
  8. package/dist/cli/commands/info.d.ts.map +1 -1
  9. package/dist/cli/commands/info.js +2 -1
  10. package/dist/cli/commands/info.js.map +1 -1
  11. package/dist/cli/commands/init.d.ts.map +1 -1
  12. package/dist/cli/commands/init.js +4 -2
  13. package/dist/cli/commands/init.js.map +1 -1
  14. package/dist/cli/index.js +102 -128
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/postinstall/claude-agents.d.ts.map +1 -1
  17. package/dist/cli/postinstall/claude-agents.js +0 -5
  18. package/dist/cli/postinstall/claude-agents.js.map +1 -1
  19. package/dist/cli/postinstall/constants.d.ts +6 -0
  20. package/dist/cli/postinstall/constants.d.ts.map +1 -1
  21. package/dist/cli/postinstall/constants.js +42 -60
  22. package/dist/cli/postinstall/constants.js.map +1 -1
  23. package/dist/cli/postinstall/inline-skills.js +2 -2
  24. package/dist/cli/postinstall/inline-skills.js.map +1 -1
  25. package/dist/cli/postinstall/main.d.ts.map +1 -1
  26. package/dist/cli/postinstall/main.js +2 -0
  27. package/dist/cli/postinstall/main.js.map +1 -1
  28. package/dist/cli/postinstall.d.ts +6 -1
  29. package/dist/cli/postinstall.d.ts.map +1 -1
  30. package/dist/cli/postinstall.js +6 -1
  31. package/dist/cli/postinstall.js.map +1 -1
  32. package/dist/cli/setup/GlobalInstaller.d.ts +1 -15
  33. package/dist/cli/setup/GlobalInstaller.d.ts.map +1 -1
  34. package/dist/cli/setup/GlobalInstaller.js +16 -115
  35. package/dist/cli/setup/GlobalInstaller.js.map +1 -1
  36. package/dist/cli/setup/GlobalInstaller.test.d.ts +2 -0
  37. package/dist/cli/setup/GlobalInstaller.test.d.ts.map +1 -0
  38. package/dist/cli/setup/GlobalInstaller.test.js +16 -0
  39. package/dist/cli/setup/GlobalInstaller.test.js.map +1 -0
  40. package/dist/cli/setup/ProjectSetup.js +2 -2
  41. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  42. package/dist/cli/setup.d.ts +1 -1
  43. package/dist/cli/setup.d.ts.map +1 -1
  44. package/dist/cli/setup.js +1 -1
  45. package/dist/cli/setup.js.map +1 -1
  46. package/dist/infra/lib/SkillRepository.js +1 -1
  47. package/dist/infra/lib/evolution/__tests__/integration.test.js +0 -42
  48. package/dist/infra/lib/evolution/__tests__/integration.test.js.map +1 -1
  49. package/hooks/scripts/__tests__/.vibe/command-log.txt +3 -3
  50. package/hooks/scripts/__tests__/clone-behaviors.test.js +33 -1
  51. package/hooks/scripts/__tests__/code-check-memory-write.test.js +81 -0
  52. package/hooks/scripts/__tests__/step-counter.test.js +21 -0
  53. package/hooks/scripts/auto-format.js +2 -11
  54. package/hooks/scripts/auto-test.js +2 -11
  55. package/hooks/scripts/clone-extract.js +146 -10
  56. package/hooks/scripts/code-check.js +27 -55
  57. package/hooks/scripts/lib/glob.js +32 -0
  58. package/hooks/scripts/lib/hook-context.js +19 -2
  59. package/hooks/scripts/post-edit.js +2 -3
  60. package/hooks/scripts/prompt-dispatcher.js +1 -1
  61. package/hooks/scripts/scope-guard.js +3 -42
  62. package/hooks/scripts/sentinel-guard.js +5 -20
  63. package/hooks/scripts/session-start.js +2 -2
  64. package/hooks/scripts/step-counter.js +35 -57
  65. package/package.json +2 -3
  66. package/skills/clone/SKILL.md +10 -216
  67. package/skills/clone/references/capture-rules.md +48 -0
  68. package/skills/clone/references/legal-and-error-recovery.md +40 -0
  69. package/skills/clone/references/refine-rules.md +61 -0
  70. package/skills/clone/references/scaffold-phases.md +59 -0
  71. package/skills/clone/references/setup-and-layout.md +30 -0
  72. package/skills/docs/SKILL.md +39 -4
  73. package/skills/docs/references/api-docs-changelog.md +34 -0
  74. package/skills/docs/references/codemaps-output.md +23 -0
  75. package/{agents/diagrammer.md → skills/docs/references/diagram-spec.md} +2 -15
  76. package/skills/exec-plan/SKILL.md +1 -1
  77. package/skills/exec-plan/templates/plan.md +1 -1
  78. package/skills/handoff/SKILL.md +3 -3
  79. package/skills/handoff/templates/handoff.md +1 -1
  80. package/skills/vibe/SKILL.md +3 -2
  81. package/skills/vibe.analyze/SKILL.md +12 -249
  82. package/skills/vibe.analyze/references/output-templates.md +188 -0
  83. package/skills/vibe.analyze/references/quality-gate.md +93 -0
  84. package/skills/vibe.clone/SKILL.md +14 -1
  85. package/skills/vibe.continue/SKILL.md +32 -0
  86. package/skills/vibe.design/SKILL.md +23 -1
  87. package/skills/vibe.design/references/ui-preview.md +20 -0
  88. package/skills/vibe.docs/SKILL.md +4 -2
  89. package/skills/vibe.figma/SKILL.md +33 -260
  90. package/skills/vibe.figma/references/branch-phases.md +113 -0
  91. package/skills/vibe.figma/references/state-schema.md +42 -0
  92. package/skills/vibe.figma/references/step-algorithms.md +204 -0
  93. package/skills/vibe.image/SKILL.md +62 -0
  94. package/skills/vibe.image/references/image-generation-examples.md +39 -0
  95. package/skills/vibe.reason/SKILL.md +3 -183
  96. package/skills/vibe.reason/references/output-format-template.md +57 -0
  97. package/skills/vibe.reason/references/quality-rubrics.md +94 -0
  98. package/skills/vibe.reason/references/worked-example.md +45 -0
  99. package/skills/vibe.review/SKILL.md +13 -348
  100. package/skills/vibe.review/references/boundary-check.md +25 -0
  101. package/skills/vibe.review/references/output-template.md +74 -0
  102. package/skills/vibe.review/references/quality-gate.md +84 -0
  103. package/skills/vibe.review/references/race-mode.md +117 -0
  104. package/skills/vibe.review/references/worked-examples.md +94 -0
  105. package/vibe/templates/claudemd-template.md +1 -1
  106. package/agents/acceptance-tester.md +0 -56
  107. package/agents/documenter.md +0 -43
  108. package/agents/figma/figma-engineer.md +0 -76
  109. package/dist/cli/postinstall/index.d.ts +0 -23
  110. package/dist/cli/postinstall/index.d.ts.map +0 -1
  111. package/dist/cli/postinstall/index.js +0 -23
  112. package/dist/cli/postinstall/index.js.map +0 -1
  113. package/dist/cli/setup/index.d.ts +0 -9
  114. package/dist/cli/setup/index.d.ts.map +0 -1
  115. package/dist/cli/setup/index.js +0 -12
  116. package/dist/cli/setup/index.js.map +0 -1
  117. package/hooks/scripts/__tests__/.vibe/memories/memories.db +0 -0
  118. package/hooks/scripts/__tests__/.vibe/memories/memories.db-shm +0 -0
  119. package/hooks/scripts/__tests__/.vibe/memories/memories.db-wal +0 -0
  120. package/hooks/scripts/evolution-engine.js +0 -91
  121. package/hooks/scripts/hud-status.js +0 -321
  122. package/hooks/scripts/skill-injector.js +0 -83
  123. package/skills/vibe.utils/SKILL.md +0 -415
@@ -452,7 +452,7 @@ At 70%+ context usage:
452
452
  ## Slash Command
453
453
 
454
454
  \`\`\`
455
- /vibe.utils --continue
455
+ /vibe.continue
456
456
  \`\`\`
457
457
 
458
458
  Restores previous session context automatically.
@@ -132,18 +132,6 @@ describe('Full evolution pipeline', () => {
132
132
  expect(cleanupResult.errors).toHaveLength(0);
133
133
  });
134
134
  });
135
- // Phase 5 Scenario 1: evolution-engine.js hook exists and is valid JS
136
- describe('Evolution hook file', () => {
137
- it('should have evolution-engine.js with PostToolUse logic', async () => {
138
- const hookPath = join(__dirname, '..', '..', '..', '..', '..', 'hooks', 'scripts', 'evolution-engine.js');
139
- expect(existsSync(hookPath)).toBe(true);
140
- const content = readFileSync(hookPath, 'utf8');
141
- expect(content).toContain('PostToolUse');
142
- expect(content).toContain('InsightExtractor');
143
- expect(content).toContain('EvolutionOrchestrator');
144
- expect(content).toContain('setImmediate');
145
- });
146
- });
147
135
  // Phase 5 Scenario 2: prompt-dispatcher gap detection
148
136
  describe('Prompt dispatcher gap detection', () => {
149
137
  it('should have gap logging code in prompt-dispatcher.js', () => {
@@ -155,25 +143,6 @@ describe('Prompt dispatcher gap detection', () => {
155
143
  expect(content).toContain('logMiss');
156
144
  });
157
145
  });
158
- // Phase 5 Scenario 3: skill-injector auto/ scan + .disabled filter
159
- describe('Skill injector auto/ directory', () => {
160
- it('should scan auto/ directories and skip .disabled files', () => {
161
- const hookPath = join(__dirname, '..', '..', '..', '..', '..', 'hooks', 'scripts', 'skill-injector.js');
162
- expect(existsSync(hookPath)).toBe(true);
163
- const content = readFileSync(hookPath, 'utf8');
164
- expect(content).toContain("'auto'");
165
- expect(content).toContain('.disabled');
166
- expect(content).toContain('project-auto');
167
- expect(content).toContain('user-auto');
168
- });
169
- it('should track usage of auto-generated skills', () => {
170
- const hookPath = join(__dirname, '..', '..', '..', '..', '..', 'hooks', 'scripts', 'skill-injector.js');
171
- const content = readFileSync(hookPath, 'utf8');
172
- expect(content).toContain('UsageTracker');
173
- expect(content).toContain('recordUsage');
174
- expect(content).toContain('generated');
175
- });
176
- });
177
146
  // Phase 5 Scenario 4 & 5 & 9: CLI commands
178
147
  describe('Evolution CLI commands', () => {
179
148
  it('should export all CLI functions', async () => {
@@ -197,17 +166,6 @@ describe('Evolution CLI commands', () => {
197
166
  expect(content).not.toContain("case 'evolution'");
198
167
  });
199
168
  });
200
- // Phase 5 Scenario 7: Ultrawork mode auto override
201
- describe('Ultrawork auto mode override', () => {
202
- it('should support mode from config (suggest/auto) in evolution-engine', () => {
203
- const hookPath = join(__dirname, '..', '..', '..', '..', '..', 'hooks', 'scripts', 'evolution-engine.js');
204
- const content = readFileSync(hookPath, 'utf8');
205
- expect(content).toContain('config.mode');
206
- expect(content).toContain("'suggest'");
207
- // Mode 'auto' comes from config.json, not hardcoded in hook
208
- expect(content).toContain('mode');
209
- });
210
- });
211
169
  // Phase 5 Scenario 8 (P3-3 동결 이후): SessionStart 는 evolution 요약을 주입하지 않는다.
212
170
  // evolution 상태 조회는 명시적 CLI(vibe evolution) 전용.
213
171
  describe('Session start evolution status', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../../../../src/infra/lib/evolution/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../../../../src/infra/lib/evolution/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- [2026-07-02T09:11:20.705Z] rm -rf /
2
- [2026-07-02T09:11:20.800Z] ls -la
3
- [2026-07-02T09:11:20.907Z] rm -rf src/infra/lib/evolution/
1
+ [2026-07-07T18:06:19.192Z] rm -rf /
2
+ [2026-07-07T18:06:19.342Z] ls -la
3
+ [2026-07-07T18:06:19.475Z] rm -rf src/infra/lib/evolution/
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { describe, it, expect } from 'vitest';
8
- import { diffStyles } from '../clone-extract.js';
8
+ import { collectSubUrls, diffStyles } from '../clone-extract.js';
9
9
  import { sectionHasNode, behaviorsBlock } from '../clone-spec.js';
10
10
 
11
11
  describe('diffStyles', () => {
@@ -28,6 +28,38 @@ describe('diffStyles', () => {
28
28
  });
29
29
  });
30
30
 
31
+ describe('collectSubUrls', () => {
32
+ it('keeps same-origin locale menu links and drops footer/external links', () => {
33
+ const urls = collectSubUrls('https://www.lgdisplay.com/kor', [
34
+ { href: '/kor/company/info/outline/greeting', text: '기업개요' },
35
+ { href: '/kor/product/tv/oled', text: 'TV' },
36
+ { href: '/eng', text: 'ENG' },
37
+ { href: '/kor/privacy', text: '개인정보처리방침' },
38
+ { href: 'https://news.lgdisplay.com/news', text: 'Newsroom' },
39
+ { href: 'https://www.youtube.com/@lgdisplay', text: 'You Tube' },
40
+ { href: '#top', text: 'TOP' },
41
+ ]);
42
+
43
+ expect(urls).toEqual([
44
+ 'https://www.lgdisplay.com/kor',
45
+ 'https://www.lgdisplay.com/kor/company/info/outline/greeting',
46
+ 'https://www.lgdisplay.com/kor/product/tv/oled',
47
+ ]);
48
+ });
49
+
50
+ it('deduplicates links after dropping query strings and hashes', () => {
51
+ const urls = collectSubUrls('https://example.com/kor', [
52
+ { href: '/kor/company?utm_source=x', text: 'Company' },
53
+ { href: '/kor/company#ceo', text: 'Company' },
54
+ ]);
55
+
56
+ expect(urls).toEqual([
57
+ 'https://example.com/kor',
58
+ 'https://example.com/kor/company',
59
+ ]);
60
+ });
61
+ });
62
+
31
63
  describe('behavior → section attachment', () => {
32
64
  const section = {
33
65
  name: 'Header',
@@ -0,0 +1,81 @@
1
+ /**
2
+ * code-check.js — C1 회귀 테스트: SQLite addObservation 조건화
3
+ *
4
+ * 검증 대상:
5
+ * - 무위반(clean) Edit → memories.db 자체가 생성되지 않음 (SQLite write 없음)
6
+ * - 위반(violation) Edit → memories.db 생성 (addObservation 기록)
7
+ * - 코드 확장자가 아닌 파일 → 동적 import 전 조기 반환 (write 없음)
8
+ *
9
+ * dist 빌드 필요 (BASE_URL = dist/tools) — `npm run build` 이후 실행.
10
+ * 패턴: 훅 스크립트 공통의 spawnSync 방식 (post-edit-dispatcher.test.js 참고).
11
+ */
12
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
13
+ import { spawnSync } from 'child_process';
14
+ import fs from 'fs';
15
+ import os from 'os';
16
+ import path from 'path';
17
+ import { fileURLToPath } from 'url';
18
+
19
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
+ const SCRIPT = path.resolve(__dirname, '..', 'code-check.js');
21
+
22
+ /**
23
+ * 격리된 임시 프로젝트에서 code-check 를 1회 실행.
24
+ * stdin 으로 PostToolUse payload 전달.
25
+ */
26
+ function runCodeCheck({ filePath, projectDir }) {
27
+ const payload = { tool_name: 'Edit', tool_input: { file_path: filePath } };
28
+ return spawnSync('node', [SCRIPT], {
29
+ input: JSON.stringify(payload),
30
+ encoding: 'utf-8',
31
+ timeout: 15000,
32
+ env: { ...process.env, CLAUDE_PROJECT_DIR: projectDir },
33
+ });
34
+ }
35
+
36
+ function memoriesDbPath(projectDir) {
37
+ return path.join(projectDir, '.vibe', 'memories', 'memories.db');
38
+ }
39
+
40
+ describe('code-check.js: 위반 시에만 SQLite 기록 (C1)', () => {
41
+ let projectDir;
42
+
43
+ beforeEach(() => {
44
+ projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-code-check-'));
45
+ });
46
+
47
+ afterEach(() => {
48
+ try { fs.rmSync(projectDir, { recursive: true, force: true }); } catch { /* ignore */ }
49
+ });
50
+
51
+ it('무위반 TS 파일 편집 → memories.db 미생성 (SQLite write 없음)', () => {
52
+ const filePath = path.join(projectDir, 'clean.ts');
53
+ fs.writeFileSync(filePath, 'export function add(a: number, b: number): number {\n return a + b;\n}\n');
54
+
55
+ const result = runCodeCheck({ filePath, projectDir });
56
+
57
+ expect(result.status).toBe(0);
58
+ expect(fs.existsSync(memoriesDbPath(projectDir))).toBe(false);
59
+ });
60
+
61
+ it('any 타입 위반이 있는 TS 파일 편집 → memories.db 생성 (SQLite write 발생)', () => {
62
+ const filePath = path.join(projectDir, 'dirty.ts');
63
+ fs.writeFileSync(filePath, 'export function foo(x: any): any {\n return x;\n}\n');
64
+
65
+ const result = runCodeCheck({ filePath, projectDir });
66
+
67
+ expect(result.status).toBe(0);
68
+ expect(result.stdout).toContain('any-type');
69
+ expect(fs.existsSync(memoriesDbPath(projectDir))).toBe(true);
70
+ });
71
+
72
+ it('코드 확장자가 아닌 파일(.md) → 동적 import 조기 반환, memories.db 미생성', () => {
73
+ const filePath = path.join(projectDir, 'notes.md');
74
+ fs.writeFileSync(filePath, "console.log('should not trigger memory write')\n");
75
+
76
+ const result = runCodeCheck({ filePath, projectDir });
77
+
78
+ expect(result.status).toBe(0);
79
+ expect(fs.existsSync(memoriesDbPath(projectDir))).toBe(false);
80
+ });
81
+ });
@@ -435,4 +435,25 @@ describe('step-counter PostToolUse hook', () => {
435
435
  expect(files).toHaveLength(1);
436
436
  });
437
437
  });
438
+
439
+ // ───────── A2/D2: 64KB 초과 stdin 페이로드 (구 단일 버퍼 리더 절단 버그 회귀) ─────────
440
+ describe('stdin 64KB 초과 페이로드 — 절단 없이 처리', () => {
441
+ it('페이로드가 64KB를 넘어도 JSON 전체를 읽어 target_file을 정확히 기록', () => {
442
+ // 구현이 64KB 단일 버퍼로 되돌아가면 JSON이 중간에 잘려 파싱 실패 →
443
+ // stdinPayload=null → jsonl 라인 자체가 기록되지 않는다.
444
+ const padding = 'x'.repeat(80000); // 총 페이로드 > 64KB 보장
445
+ runCounter({
446
+ payload: {
447
+ tool_name: 'Edit',
448
+ tool_input: { file_path: 'src/foo.ts', padding },
449
+ tool_response: {},
450
+ },
451
+ projectDir,
452
+ });
453
+ const lines = readJsonl(runJsonl);
454
+ expect(lines).toHaveLength(1);
455
+ expect(lines[0].target_file).toBe('src/foo.ts');
456
+ expect(lines[0].tool).toBe('Edit');
457
+ });
458
+ });
438
459
  });
@@ -24,15 +24,6 @@ const PYTHON_EXT_RE = /\.py$/;
24
24
  const GO_EXT_RE = /\.go$/;
25
25
  const FORMAT_TIMEOUT_MS = 5000;
26
26
 
27
- function getFilePath(ctx) {
28
- try {
29
- const input = JSON.parse(ctx.toolInput || '{}');
30
- return input.file_path || input.path || '';
31
- } catch {
32
- return '';
33
- }
34
- }
35
-
36
27
  // PATH 직접 스캔 — `which` execSync는 매 파일 저장마다 자식 프로세스를 동기
37
28
  // spawn하므로, fs.existsSync로 대체하고 프로세스 내 캐싱한다.
38
29
  const _binCache = new Map();
@@ -109,13 +100,13 @@ async function formatFile(filePath) {
109
100
 
110
101
  /**
111
102
  * in-process 진입점 — 포맷 실행. finding 문자열 배열 반환.
112
- * @param {{ toolInput: string }} ctx
103
+ * @param {{ filePath: string }} ctx
113
104
  * @returns {Promise<{ exitCode: number, findings: string[] }>}
114
105
  */
115
106
  export async function run(ctx) {
116
107
  const findings = [];
117
108
  try {
118
- const filePath = getFilePath(ctx);
109
+ const filePath = ctx.filePath;
119
110
  if (filePath) {
120
111
  const finding = await formatFile(filePath);
121
112
  if (finding) findings.push(finding);
@@ -33,15 +33,6 @@ const DEBOUNCE_COOLDOWN_MS = 120_000;
33
33
  /** debounce 상태 파일 경로 */
34
34
  const DEBOUNCE_STATE_FILE = path.join(PROJECT_DIR, '.vibe', 'metrics', 'auto-test-state.json');
35
35
 
36
- function getFilePath(ctx) {
37
- try {
38
- const input = JSON.parse(ctx.toolInput || '{}');
39
- return input.file_path || input.path || '';
40
- } catch {
41
- return '';
42
- }
43
- }
44
-
45
36
  function isTestFile(filePath) {
46
37
  return TEST_SUFFIXES.some(s => filePath.includes(s));
47
38
  }
@@ -163,13 +154,13 @@ function updateDebounceState(testFile, srcFile) {
163
154
 
164
155
  /**
165
156
  * in-process 진입점 — 테스트 실행. findings 반환.
166
- * @param {{ toolInput: string }} ctx
157
+ * @param {{ filePath: string }} ctx
167
158
  * @returns {Promise<{ exitCode: number, findings: string[] }>}
168
159
  */
169
160
  export async function run(ctx) {
170
161
  const findings = [];
171
162
  try {
172
- const filePath = getFilePath(ctx);
163
+ const filePath = ctx.filePath;
173
164
  if (!filePath || !CODE_EXT_RE.test(filePath)) return { exitCode: 0, findings };
174
165
 
175
166
  const mode = getTestMode();
@@ -78,6 +78,11 @@ const CSS_PROPS = [
78
78
  'mask-image', 'mask-size', 'mask-position', 'clip-path',
79
79
  ];
80
80
 
81
+ const SUB_URL_LIMIT = 200;
82
+ const SUB_EXCLUDE_TEXT_RE = /^(?:검색|search|top|home|kor|eng|chn|vtn|language|언어|개인정보|privacy|문의|제안|sitemap|사이트맵|youtube|뉴스룸|newsroom|cookie|닫기|partner|파트너)$/i;
83
+ const SUB_EXCLUDE_PATH_RE = /\/(?:search|sitemap|privacy|contact|inquiry|cookie|login|auth|policy)(?:\/|$)/i;
84
+ const SUB_EXCLUDE_EXT_RE = /\.(?:pdf|zip|jpe?g|png|gif|webp|svg|mp4|mov|avi|docx?|xlsx?|pptx?)$/i;
85
+
81
86
  // ─── CLI parse ──────────────────────────────────────────────────────
82
87
  function parseArgs(argv) {
83
88
  const [, , cmd, urlArg, ...rest] = argv;
@@ -104,6 +109,74 @@ function parseViewport(v) {
104
109
  };
105
110
  }
106
111
 
112
+ function localePrefixOf(rawUrl) {
113
+ const first = new URL(rawUrl).pathname.split('/').filter(Boolean)[0];
114
+ if (!first || !/^[a-z]{2,3}(?:-[a-z]{2})?$/i.test(first)) return null;
115
+ return `/${first}`;
116
+ }
117
+
118
+ function normalizeSubUrl(startUrl, href) {
119
+ if (!href || typeof href !== 'string') return null;
120
+ try {
121
+ const target = new URL(href, startUrl);
122
+ if (target.protocol !== 'http:' && target.protocol !== 'https:') return null;
123
+ target.hash = '';
124
+ target.search = '';
125
+ target.pathname = target.pathname.replace(/\/+$/, '') || '/';
126
+ return target;
127
+ } catch {
128
+ return null;
129
+ }
130
+ }
131
+
132
+ function isSameMenuScope(target, start, localePrefix) {
133
+ if (target.origin !== start.origin) return false;
134
+ if (!localePrefix) return true;
135
+ return target.pathname === localePrefix || target.pathname.startsWith(`${localePrefix}/`);
136
+ }
137
+
138
+ function isExcludedSubLink(target, text) {
139
+ const label = String(text || '').trim();
140
+ if (SUB_EXCLUDE_TEXT_RE.test(label)) return true;
141
+ if (SUB_EXCLUDE_PATH_RE.test(target.pathname)) return true;
142
+ return SUB_EXCLUDE_EXT_RE.test(target.pathname);
143
+ }
144
+
145
+ function collectSubUrls(startUrl, links, limit = SUB_URL_LIMIT) {
146
+ const start = normalizeSubUrl(startUrl, startUrl);
147
+ if (!start) return [];
148
+ const localePrefix = localePrefixOf(start.href);
149
+ const urls = [start.href];
150
+ const seen = new Set(urls);
151
+
152
+ for (const link of links) {
153
+ if (urls.length >= limit) break;
154
+ const target = normalizeSubUrl(start.href, link.href);
155
+ if (!target || seen.has(target.href)) continue;
156
+ if (!isSameMenuScope(target, start, localePrefix)) continue;
157
+ if (isExcludedSubLink(target, link.text)) continue;
158
+ seen.add(target.href);
159
+ urls.push(target.href);
160
+ }
161
+
162
+ return urls;
163
+ }
164
+
165
+ function findSitemapUrl(startUrl, links) {
166
+ const start = normalizeSubUrl(startUrl, startUrl);
167
+ if (!start) return null;
168
+ const localePrefix = localePrefixOf(start.href);
169
+
170
+ for (const link of links) {
171
+ const label = String(link.text || '').trim();
172
+ if (!/sitemap|사이트맵/i.test(`${label} ${link.href}`)) continue;
173
+ const target = normalizeSubUrl(start.href, link.href);
174
+ if (target && isSameMenuScope(target, start, localePrefix)) return target.href;
175
+ }
176
+
177
+ return null;
178
+ }
179
+
107
180
  // ─── Puppeteer dynamic loader (optional dep) ────────────────────────
108
181
  async function loadPuppeteer() {
109
182
  try {
@@ -905,6 +978,14 @@ const SEO_EXTRACT = `(function () {
905
978
  return Array.from(new Set(icons.concat(og)));
906
979
  })`;
907
980
 
981
+ const SUB_LINK_EXTRACT = `(function () {
982
+ const links = Array.from(document.querySelectorAll('a[href]')).map((a) => ({
983
+ href: a.getAttribute('href'),
984
+ text: (a.innerText || a.textContent || '').replace(/\\s+/g, ' ').trim(),
985
+ }));
986
+ return { links };
987
+ })`;
988
+
908
989
  // HTML sanitization: strip scripts/analytics before saving
909
990
  function sanitizeHtml(html) {
910
991
  return html
@@ -914,6 +995,65 @@ function sanitizeHtml(html) {
914
995
  .replace(/\son[a-z]+='[^']*'/gi, '');
915
996
  }
916
997
 
998
+ async function newClonePage(browser) {
999
+ const page = await browser.newPage();
1000
+ await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
1001
+ await page.setUserAgent(
1002
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ' +
1003
+ '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
1004
+ );
1005
+ await page.setCacheEnabled(false);
1006
+ return page;
1007
+ }
1008
+
1009
+ async function discoverSubUrls({ url, opts }) {
1010
+ if (!url) throw new Error('URL is required');
1011
+ if (!opts.out) throw new Error('--out=<file> is required');
1012
+
1013
+ if (!opts.ignoreRobots) {
1014
+ const blocked = await checkRobots(url);
1015
+ if (blocked) {
1016
+ throw new Error(
1017
+ `robots.txt disallows ${url}. Pass --ignore-robots only with the site owner's permission.`,
1018
+ );
1019
+ }
1020
+ }
1021
+
1022
+ const puppeteer = await loadPuppeteer();
1023
+ const browser = await puppeteer.launch({
1024
+ headless: 'new',
1025
+ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
1026
+ });
1027
+
1028
+ try {
1029
+ const page = await newClonePage(browser);
1030
+ await page.goto(url, { waitUntil: 'networkidle2', timeout: 90000 });
1031
+ await wait(800);
1032
+
1033
+ let source = 'menu';
1034
+ let sourceUrl = url;
1035
+ let { links } = await page.evaluate(`(${SUB_LINK_EXTRACT})()`);
1036
+ const sitemapUrl = findSitemapUrl(url, links);
1037
+ if (sitemapUrl) {
1038
+ await page.goto(sitemapUrl, { waitUntil: 'networkidle2', timeout: 90000 });
1039
+ await wait(800);
1040
+ source = 'sitemap';
1041
+ sourceUrl = sitemapUrl;
1042
+ ({ links } = await page.evaluate(`(${SUB_LINK_EXTRACT})()`));
1043
+ }
1044
+
1045
+ const urls = collectSubUrls(url, links);
1046
+ fs.mkdirSync(path.dirname(opts.out), { recursive: true });
1047
+ fs.writeFileSync(
1048
+ opts.out,
1049
+ JSON.stringify({ meta: { url, source, sourceUrl, count: urls.length }, urls }, null, 2),
1050
+ );
1051
+ process.stdout.write(`[clone-extract] suburls ${urls.length} → ${opts.out}\n`);
1052
+ } finally {
1053
+ await browser.close();
1054
+ }
1055
+ }
1056
+
917
1057
  // ─── Main capture flow ──────────────────────────────────────────────
918
1058
  async function capture({ url, opts }) {
919
1059
  if (!url) throw new Error('URL is required');
@@ -954,14 +1094,8 @@ async function capture({ url, opts }) {
954
1094
  });
955
1095
 
956
1096
  try {
957
- const page = await browser.newPage();
1097
+ const page = await newClonePage(browser);
958
1098
  await page.setViewport(viewport);
959
- await page.setUserAgent(
960
- 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ' +
961
- '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
962
- );
963
- // disable cache to get fresh assets
964
- await page.setCacheEnabled(false);
965
1099
 
966
1100
  await page.goto(url, { waitUntil: 'networkidle2', timeout: 90000 });
967
1101
  await scrollToBottom(page);
@@ -1140,16 +1274,18 @@ const isMain = process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('
1140
1274
  if (isMain) {
1141
1275
  const { cmd, url, opts } = parseArgs(process.argv);
1142
1276
 
1143
- if (cmd !== 'capture') {
1277
+ if (cmd !== 'capture' && cmd !== 'suburls') {
1144
1278
  console.error('Usage: node clone-extract.js capture <URL> --out=<dir> --viewport=WxH[@DPR] --bp=mo|pc [--stealth] [--ignore-robots] [--no-interact] [--wait=ms]');
1279
+ console.error(' node clone-extract.js suburls <URL> --out=<file> [--ignore-robots]');
1145
1280
  process.exit(1);
1146
1281
  }
1147
1282
 
1148
- capture({ url, opts }).catch((err) => {
1283
+ const run = cmd === 'suburls' ? discoverSubUrls : capture;
1284
+ run({ url, opts }).catch((err) => {
1149
1285
  console.error(`[clone-extract] FAIL: ${err.message}`);
1150
1286
  if (process.env.DEBUG) console.error(err.stack);
1151
1287
  process.exit(1);
1152
1288
  });
1153
1289
  }
1154
1290
 
1155
- export { diffStyles };
1291
+ export { collectSubUrls, diffStyles };